Skip to content

Rollup of 18 pull requests #113097

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 68 commits into from
Closed
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
15d92d6
Add gamma function to f32 and f64
ankane Jul 26, 2022
0415d8d
Fixed CI
ankane Jul 26, 2022
61a73d4
Added tracking issue
ankane Jul 28, 2022
37b3466
Add more tests for gamma function
ankane Aug 2, 2022
f05c188
Fix negative zero tests for gamma function
ankane Aug 2, 2022
5a57f24
Add ln_gamma function to f32 and f64
ankane Mar 5, 2023
6fa99de
Use the LLVM option NoTrapAfterNoreturn
majaha Apr 18, 2023
88ab319
Reapply: Mark drop calls in landing pads cold instead of noinline
erikdesjardins Mar 10, 2022
b127a0f
remove is_rust_llvm check, since fixes are in final llvm 14 release
erikdesjardins Mar 11, 2022
0928728
Add back missing llvm_util import
InnovativeInventor Sep 21, 2022
39ec96f
Address Erik's feedback
InnovativeInventor Nov 24, 2022
e13e645
Add back FIXME for bjorn3
InnovativeInventor Nov 24, 2022
5ca4204
Fix failing test (invoke void %g() is correct behavior)
InnovativeInventor Jan 12, 2023
4773fbc
Revert "Fix failing test (invoke void %g() is correct behavior)"
InnovativeInventor Jan 12, 2023
c975e16
Add regression test for #97217
InnovativeInventor Jan 12, 2023
504c832
Comply with linter
InnovativeInventor Jan 12, 2023
a056883
Add min-llvm-version to regression test
InnovativeInventor Jan 13, 2023
c7083c5
Use min-llvm-version in tests
InnovativeInventor Jan 13, 2023
ed3030c
Add ignore-debug to unwind-landingpad-inline test
InnovativeInventor Feb 4, 2023
bed624d
Remove references to LLVM 14.0.0, which is no longer supported
InnovativeInventor May 15, 2023
0d61104
Remove unnecessary llvm_util import
InnovativeInventor May 15, 2023
e5b84f3
Remove SmallVec
InnovativeInventor May 17, 2023
b1d60bc
refactor executing tests to centralize actually invoking tests
pietroalbini May 26, 2023
fa451fe
remove nested function from run_test
pietroalbini May 26, 2023
2f7fd2e
add StaticBenchAsTestFn and DynBenchAsTestFn to convert benches to tests
pietroalbini May 26, 2023
b82eb28
convert benches to tests in subprocess if we're not benchmarking
pietroalbini May 26, 2023
142f453
add tests on running benchmarks with -Z panic-abort-tests
pietroalbini May 26, 2023
58d9d8c
Revert "Adjusting test to needs-unwind, with linking issue"
pietroalbini May 26, 2023
6c95fa3
Always name the return place.
cjgillot May 15, 2023
2c69f27
Restrict test to opaque pointers.
cjgillot May 24, 2023
7e75612
Assume less names.
cjgillot May 29, 2023
5505f91
Fix 111905
c410-f3r Jun 18, 2023
462c5c4
Update LLVM submodule
Amanieu Jun 19, 2023
dc76991
Remove `LineColumn`, `Span::start`, `Span::end`
jhpratt May 14, 2023
87ec073
`Span::{before, after}` → `Span::{start, end}`
jhpratt May 14, 2023
a1cd8c3
Add `Span::{line, column}`
jhpratt May 14, 2023
8dc3b85
Fix tests
jhpratt May 14, 2023
cd1c1b1
Update to proc-macro2 1.0.57 to unblock proc_macro_span changes
dtolnay May 15, 2023
abd0677
Merge proc_macro_span_shrink and proc_macro_span
jhpratt Jun 6, 2023
21d9fd7
Delete use of proc_macro_span_shrink from proc-macro2
dtolnay Jun 8, 2023
6159075
Remove outdated import in r-a proc macro server.
m-ou-se Jun 21, 2023
d1f68ea
Better diagnostics for dlltool errors.
jfgoog Jun 13, 2023
c37afcd
Enable zlib in LLVM on aarch64-apple-darwin
cbeuw Jun 22, 2023
9fc2da1
Forward `io::{Read,Seek,Write}` impls of `File` to `&File`
tbu- Dec 31, 2022
11fecf6
Add `Read`, `Write` and `Seek` impls for `Arc<File>` where appropriate
tbu- Dec 31, 2022
d43131b
Bump download-ci-llvm-stamp
cbeuw Jun 24, 2023
fbb2079
Use `CoverageKind::as_operand_id` instead of manually reimplementing it
Zalathar Jun 26, 2023
3224ea4
Export AnalysisResults trait in rustc_mir_dataflow
floriangru Jun 27, 2023
48544c1
Make `rustc_on_unimplemented` std-agnostic
Rageking8 Jun 26, 2023
b8e4c54
Fix invalid HTML DIV tag used in HEAD
GuillaumeGomez Jun 27, 2023
1b7efb5
remove an unused struct `ForbiddenNonLifetimeParam`
TaKO8Ki Jun 27, 2023
8352c02
avoid using `format!("{}", ..)`
TaKO8Ki Jun 27, 2023
1dba5af
Rollup merge of #94748 - tbu-:pr_file_arc, r=Amanieu
TaKO8Ki Jun 27, 2023
448a75b
Rollup merge of #99747 - ankane:float_gamma, r=joshtriplett
TaKO8Ki Jun 27, 2023
047dd55
Rollup merge of #102099 - InnovativeInventor:re-cold-land, r=nikic
TaKO8Ki Jun 27, 2023
7a9bfd4
Rollup merge of #110494 - majaha:noTrapAfterNoreturn, r=nikic
TaKO8Ki Jun 27, 2023
90adbdc
Rollup merge of #111571 - jhpratt:proc-macro-span, r=m-ou-se
TaKO8Ki Jun 27, 2023
a5f5328
Rollup merge of #111618 - cjgillot:name-return-place, r=tmiasko
TaKO8Ki Jun 27, 2023
1817bb2
Rollup merge of #111923 - c410-f3r:impl, r=oli-obk
TaKO8Ki Jun 27, 2023
1d7f087
Rollup merge of #111992 - ferrocene:pa-panic-abort-tests-bench, r=m-o…
TaKO8Ki Jun 27, 2023
270ee72
Rollup merge of #112591 - jfgoog:better-dlltool-diagnostics, r=Waffle…
TaKO8Ki Jun 27, 2023
22681be
Rollup merge of #112816 - Amanieu:llvm-riscv-arch, r=cuviper
TaKO8Ki Jun 27, 2023
0c200a4
Rollup merge of #112931 - cbeuw:apple-zlib, r=Mark-Simulacrum
TaKO8Ki Jun 27, 2023
b6cf0ac
Rollup merge of #113054 - Rageking8:make-`rustc_on_unimplemented`-std…
TaKO8Ki Jun 27, 2023
10f2b9b
Rollup merge of #113079 - Zalathar:as-operand-id, r=oli-obk
TaKO8Ki Jun 27, 2023
3493d5d
Rollup merge of #113089 - floriangru:mut_analyses_followup, r=oli-obk
TaKO8Ki Jun 27, 2023
6e6a1bb
Rollup merge of #113094 - GuillaumeGomez:fix-invalid-div-tag-in-head,…
TaKO8Ki Jun 27, 2023
9257837
Rollup merge of #113096 - TaKO8Ki:remove-unused-struct, r=oli-obk
TaKO8Ki Jun 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -2580,9 +2580,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"

[[package]]
name = "proc-macro2"
version = "1.0.56"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [
"unicode-ident",
]
7 changes: 0 additions & 7 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
@@ -77,13 +77,6 @@ pub struct ForbiddenLifetimeBound {
pub spans: Vec<Span>,
}

#[derive(Diagnostic)]
#[diag(ast_passes_forbidden_non_lifetime_param)]
pub struct ForbiddenNonLifetimeParam {
#[primary_span]
pub spans: Vec<Span>,
}

#[derive(Diagnostic)]
#[diag(ast_passes_fn_param_too_many)]
pub struct FnParamTooMany {
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1421,7 +1421,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
self.cx
}

fn do_not_inline(&mut self, _llret: RValue<'gcc>) {
fn apply_attrs_to_cleanup_callsite(&mut self, _llret: RValue<'gcc>) {
// FIXME(bjorn3): implement
}

3 changes: 2 additions & 1 deletion compiler/rustc_codegen_llvm/messages.ftl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err}

codegen_llvm_dlltool_fail_import_library =
Dlltool could not create import library: {$stdout}
Dlltool could not create import library with {$dlltool_path} {$dlltool_args}:
{$stdout}
{$stderr}

codegen_llvm_dynamic_linking_with_lto =
43 changes: 24 additions & 19 deletions compiler/rustc_codegen_llvm/src/back/archive.rs
Original file line number Diff line number Diff line change
@@ -198,25 +198,24 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
"arm" => ("arm", "--32"),
_ => panic!("unsupported arch {}", sess.target.arch),
};
let result = std::process::Command::new(&dlltool)
.args([
"-d",
def_file_path.to_str().unwrap(),
"-D",
lib_name,
"-l",
output_path.to_str().unwrap(),
"-m",
dlltool_target_arch,
"-f",
dlltool_target_bitness,
"--no-leading-underscore",
"--temp-prefix",
temp_prefix.to_str().unwrap(),
])
.output();

match result {
let mut dlltool_cmd = std::process::Command::new(&dlltool);
dlltool_cmd.args([
"-d",
def_file_path.to_str().unwrap(),
"-D",
lib_name,
"-l",
output_path.to_str().unwrap(),
"-m",
dlltool_target_arch,
"-f",
dlltool_target_bitness,
"--no-leading-underscore",
"--temp-prefix",
temp_prefix.to_str().unwrap(),
]);

match dlltool_cmd.output() {
Err(e) => {
sess.emit_fatal(ErrorCallingDllTool {
dlltool_path: dlltool.to_string_lossy(),
@@ -226,6 +225,12 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
// dlltool returns '0' on failure, so check for error output instead.
Ok(output) if !output.stderr.is_empty() => {
sess.emit_fatal(DlltoolFailImportLibrary {
dlltool_path: dlltool.to_string_lossy(),
dlltool_args: dlltool_cmd
.get_args()
.map(|arg| arg.to_string_lossy())
.collect::<Vec<_>>()
.join(" "),
stdout: String::from_utf8_lossy(&output.stdout),
stderr: String::from_utf8_lossy(&output.stderr),
})
8 changes: 5 additions & 3 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1221,9 +1221,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) }
}

fn do_not_inline(&mut self, llret: &'ll Value) {
let noinline = llvm::AttributeKind::NoInline.create_attr(self.llcx);
attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[noinline]);
fn apply_attrs_to_cleanup_callsite(&mut self, llret: &'ll Value) {
// Cleanup is always the cold path.
let cold_inline = llvm::AttributeKind::Cold.create_attr(self.llcx);

attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[cold_inline]);
}
}

2 changes: 2 additions & 0 deletions compiler/rustc_codegen_llvm/src/errors.rs
Original file line number Diff line number Diff line change
@@ -81,6 +81,8 @@ pub(crate) struct ErrorCallingDllTool<'a> {
#[derive(Diagnostic)]
#[diag(codegen_llvm_dlltool_fail_import_library)]
pub(crate) struct DlltoolFailImportLibrary<'a> {
pub dlltool_path: Cow<'a, str>,
pub dlltool_args: String,
pub stdout: Cow<'a, str>,
pub stderr: Cow<'a, str>,
}
10 changes: 3 additions & 7 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
@@ -204,7 +204,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
self.funclet(fx),
);
if fx.mir[self.bb].is_cleanup {
bx.do_not_inline(invokeret);
bx.apply_attrs_to_cleanup_callsite(invokeret);
}

if let Some((ret_dest, target)) = destination {
@@ -219,11 +219,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
} else {
let llret = bx.call(fn_ty, fn_attrs, Some(&fn_abi), fn_ptr, &llargs, self.funclet(fx));
if fx.mir[self.bb].is_cleanup {
// Cleanup is always the cold path. Don't inline
// drop glue. Also, when there is a deeply-nested
// struct, there are "symmetry" issues that cause
// exponential inlining - see issue #41696.
bx.do_not_inline(llret);
bx.apply_attrs_to_cleanup_callsite(llret);
}

if let Some((ret_dest, target)) = destination {
@@ -1618,7 +1614,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let fn_ty = bx.fn_decl_backend_type(&fn_abi);

let llret = bx.call(fn_ty, None, Some(&fn_abi), fn_ptr, &[], funclet.as_ref());
bx.do_not_inline(llret);
bx.apply_attrs_to_cleanup_callsite(llret);

bx.unreachable();

3 changes: 1 addition & 2 deletions compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
Original file line number Diff line number Diff line change
@@ -327,8 +327,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

let local_ref = &self.locals[local];

// FIXME Should the return place be named?
let name = if bx.sess().fewer_names() || local == mir::RETURN_PLACE {
let name = if bx.sess().fewer_names() {
None
} else {
Some(match whole_local_var.or(fallback_var.clone()) {
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/traits/builder.rs
Original file line number Diff line number Diff line change
@@ -332,5 +332,5 @@ pub trait BuilderMethods<'a, 'tcx>:
) -> Self::Value;
fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;

fn do_not_inline(&mut self, llret: Self::Value);
fn apply_attrs_to_cleanup_callsite(&mut self, llret: Self::Value);
}
2 changes: 2 additions & 0 deletions compiler/rustc_expand/messages.ftl
Original file line number Diff line number Diff line change
@@ -80,6 +80,8 @@ expand_meta_var_dif_seq_matchers = {$msg}
expand_meta_var_expr_unrecognized_var =
variable `{$key}` is not recognized in meta-variable expression

expand_missing_count_fragment =
related fragment that refers the `count` meta-variable expression was not found
expand_module_circular =
circular modules: {$modules}

7 changes: 7 additions & 0 deletions compiler/rustc_expand/src/errors.rs
Original file line number Diff line number Diff line change
@@ -407,3 +407,10 @@ pub struct DuplicateMatcherBinding {
#[label(expand_label2)]
pub prev: Span,
}

#[derive(Diagnostic)]
#[diag(expand_missing_count_fragment)]
pub(crate) struct MissingCountFragment {
#[primary_span]
pub span: Span,
}
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/mbe/metavar_expr.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ use rustc_span::Span;
#[derive(Debug, Clone, PartialEq, Encodable, Decodable)]
pub(crate) enum MetaVarExpr {
/// The number of repetitions of an identifier, optionally limited to a number
/// of outer-most repetition depths. If the depth limit is `None` then the depth is unlimited.
/// of outer-most repetition depths.
Count(Ident, Option<usize>),

/// Ignore a meta-variable for repetition without expansion.
9 changes: 6 additions & 3 deletions compiler/rustc_expand/src/mbe/transcribe.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::base::ExtCtxt;
use crate::errors::{
CountRepetitionMisplaced, MetaVarExprUnrecognizedVar, MetaVarsDifSeqMatchers, MustRepeatOnce,
NoSyntaxVarsExprRepeat, VarStillRepeating,
CountRepetitionMisplaced, MetaVarExprUnrecognizedVar, MetaVarsDifSeqMatchers,
MissingCountFragment, MustRepeatOnce, NoSyntaxVarsExprRepeat, VarStillRepeating,
};
use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, MatchedTokenTree, NamedMatch};
use crate::mbe::{self, MetaVarExpr};
@@ -448,6 +448,9 @@ fn count_repetitions<'a>(
}
}
MatchedSeq(named_matches) => {
if named_matches.is_empty() {
return Err(cx.create_err(MissingCountFragment { span: sp.entire() }));
}
let new_declared_lhs_depth = declared_lhs_depth + 1;
match depth_opt {
None => named_matches
@@ -506,7 +509,7 @@ fn out_of_bounds_err<'a>(
)
} else {
format!(
"depth parameter on meta-variable expression `{ty}` \
"depth parameter of meta-variable expression `{ty}` \
must be less than {max}"
)
};
23 changes: 11 additions & 12 deletions compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ use crate::base::ExtCtxt;
use pm::bridge::{
server, DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree,
};
use pm::{Delimiter, Level, LineColumn};
use pm::{Delimiter, Level};
use rustc_ast as ast;
use rustc_ast::token;
use rustc_ast::tokenstream::{self, Spacing::*, TokenStream};
@@ -648,23 +648,22 @@ impl server::Span for Rustc<'_, '_> {

Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize }
}

fn start(&mut self, span: Self::Span) -> LineColumn {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
LineColumn { line: loc.line, column: loc.col.to_usize() }
fn start(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_lo()
}

fn end(&mut self, span: Self::Span) -> LineColumn {
let loc = self.sess().source_map().lookup_char_pos(span.hi());
LineColumn { line: loc.line, column: loc.col.to_usize() }
fn end(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_hi()
}

fn before(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_lo()
fn line(&mut self, span: Self::Span) -> usize {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
loc.line
}

fn after(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_hi()
fn column(&mut self, span: Self::Span) -> usize {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
loc.col.to_usize() + 1
}

fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
Original file line number Diff line number Diff line change
@@ -139,7 +139,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
tcx,
generics,
diag,
&format!("{}", proj.self_ty()),
&proj.self_ty().to_string(),
&path,
None,
matching_span,
@@ -153,7 +153,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
tcx,
generics,
diag,
&format!("{}", proj.self_ty()),
&proj.self_ty().to_string(),
&path,
None,
matching_span,
2 changes: 2 additions & 0 deletions compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
@@ -437,6 +437,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
// it prevents control flow from "falling through" into whatever code
// happens to be laid out next in memory.
Options.TrapUnreachable = true;
// But don't emit traps after other traps or no-returns unnecessarily.
Options.NoTrapAfterNoreturn = true;
}

if (Singlethread) {
2 changes: 1 addition & 1 deletion compiler/rustc_mir_dataflow/src/framework/mod.rs
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ pub mod graphviz;
pub mod lattice;
mod visitor;

pub use self::cursor::{ResultsClonedCursor, ResultsCursor, ResultsRefCursor};
pub use self::cursor::{AnalysisResults, ResultsClonedCursor, ResultsCursor, ResultsRefCursor};
pub use self::direction::{Backward, Direction, Forward};
pub use self::engine::{Engine, EntrySets, Results, ResultsCloned};
pub use self::lattice::{JoinSemiLattice, MeetSemiLattice};
8 changes: 4 additions & 4 deletions compiler/rustc_mir_dataflow/src/lib.rs
Original file line number Diff line number Diff line change
@@ -27,10 +27,10 @@ pub use self::drop_flag_effects::{
on_lookup_result_bits,
};
pub use self::framework::{
fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, Backward, CallReturnPlaces,
CloneAnalysis, Direction, Engine, Forward, GenKill, GenKillAnalysis, JoinSemiLattice, Results,
ResultsCloned, ResultsClonedCursor, ResultsCursor, ResultsRefCursor, ResultsVisitable,
ResultsVisitor, SwitchIntEdgeEffects,
fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, AnalysisResults, Backward,
CallReturnPlaces, CloneAnalysis, Direction, Engine, Forward, GenKill, GenKillAnalysis,
JoinSemiLattice, Results, ResultsCloned, ResultsClonedCursor, ResultsCursor, ResultsRefCursor,
ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects,
};

use self::move_paths::MoveData;
17 changes: 2 additions & 15 deletions compiler/rustc_mir_transform/src/coverage/debug.rs
Original file line number Diff line number Diff line change
@@ -277,14 +277,7 @@ impl DebugCounters {

pub fn add_counter(&mut self, counter_kind: &CoverageKind, some_block_label: Option<String>) {
if let Some(counters) = &mut self.some_counters {
let id: ExpressionOperandId = match *counter_kind {
CoverageKind::Counter { id, .. } => id.into(),
CoverageKind::Expression { id, .. } => id.into(),
_ => bug!(
"the given `CoverageKind` is not an counter or expression: {:?}",
counter_kind
),
};
let id = counter_kind.as_operand_id();
counters
.try_insert(id, DebugCounter::new(counter_kind.clone(), some_block_label))
.expect("attempt to add the same counter_kind to DebugCounters more than once");
@@ -330,13 +323,7 @@ impl DebugCounters {
}
}

let id: ExpressionOperandId = match *counter_kind {
CoverageKind::Counter { id, .. } => id.into(),
CoverageKind::Expression { id, .. } => id.into(),
_ => {
bug!("the given `CoverageKind` is not an counter or expression: {:?}", counter_kind)
}
};
let id = counter_kind.as_operand_id();
if self.some_counters.is_some() && (counter_format.block || !counter_format.id) {
let counters = self.some_counters.as_ref().unwrap();
if let Some(DebugCounter { some_block_label: Some(block_label), .. }) =
2 changes: 1 addition & 1 deletion library/core/src/convert/mod.rs
Original file line number Diff line number Diff line change
@@ -532,7 +532,7 @@ pub trait Into<T>: Sized {
#[rustc_diagnostic_item = "From"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(on(
all(_Self = "&str", T = "std::string::String"),
all(_Self = "&str", any(T = "alloc::string::String", T = "std::string::String")),
note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
))]
pub trait From<T>: Sized {
8 changes: 4 additions & 4 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
@@ -26,13 +26,13 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
on(
_Self = "std::ops::RangeTo<Idx>",
any(_Self = "core::ops::RangeTo<Idx>", _Self = "std::ops::RangeTo<Idx>"),
label = "if you meant to iterate until a value, add a starting value",
note = "`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \
bounded `Range`: `0..end`"
),
on(
_Self = "std::ops::RangeToInclusive<Idx>",
any(_Self = "core::ops::RangeToInclusive<Idx>", _Self = "std::ops::RangeToInclusive<Idx>"),
label = "if you meant to iterate until a value (including it), add a starting value",
note = "`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \
to have a bounded `RangeInclusive`: `0..=end`"
@@ -43,15 +43,15 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
),
on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"),
on(
_Self = "std::vec::Vec<T, A>",
any(_Self = "alloc::vec::Vec<T, A>", _Self = "std::vec::Vec<T, A>"),
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
),
on(
_Self = "&str",
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
),
on(
_Self = "std::string::String",
any(_Self = "alloc::string::String", _Self = "std::string::String"),
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
),
on(
28 changes: 14 additions & 14 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
@@ -575,59 +575,59 @@ impl<T: ?Sized> Copy for &T {}
#[lang = "sync"]
#[rustc_on_unimplemented(
on(
_Self = "std::cell::OnceCell<T>",
any(_Self = "core::cell:OnceCell<T>", _Self = "std::cell::OnceCell<T>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead"
),
on(
_Self = "std::cell::Cell<u8>",
any(_Self = "core::cell::Cell<u8>", _Self = "std::cell::Cell<u8>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead",
),
on(
_Self = "std::cell::Cell<u16>",
any(_Self = "core::cell::Cell<u16>", _Self = "std::cell::Cell<u16>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU16` instead",
),
on(
_Self = "std::cell::Cell<u32>",
any(_Self = "core::cell::Cell<u32>", _Self = "std::cell::Cell<u32>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU32` instead",
),
on(
_Self = "std::cell::Cell<u64>",
any(_Self = "core::cell::Cell<u64>", _Self = "std::cell::Cell<u64>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU64` instead",
),
on(
_Self = "std::cell::Cell<usize>",
any(_Self = "core::cell::Cell<usize>", _Self = "std::cell::Cell<usize>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicUsize` instead",
),
on(
_Self = "std::cell::Cell<i8>",
any(_Self = "core::cell::Cell<i8>", _Self = "std::cell::Cell<i8>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI8` instead",
),
on(
_Self = "std::cell::Cell<i16>",
any(_Self = "core::cell::Cell<i16>", _Self = "std::cell::Cell<i16>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI16` instead",
),
on(
_Self = "std::cell::Cell<i32>",
any(_Self = "core::cell::Cell<i32>", _Self = "std::cell::Cell<i32>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead",
),
on(
_Self = "std::cell::Cell<i64>",
any(_Self = "core::cell::Cell<i64>", _Self = "std::cell::Cell<i64>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI64` instead",
),
on(
_Self = "std::cell::Cell<isize>",
any(_Self = "core::cell::Cell<isize>", _Self = "std::cell::Cell<isize>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicIsize` instead",
),
on(
_Self = "std::cell::Cell<bool>",
any(_Self = "core::cell::Cell<bool>", _Self = "std::cell::Cell<bool>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead",
),
on(
_Self = "std::cell::Cell<T>",
any(_Self = "core::cell::Cell<T>", _Self = "std::cell::Cell<T>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`",
),
on(
_Self = "std::cell::RefCell<T>",
any(_Self = "core::cell::RefCell<T>", _Self = "std::cell::RefCell<T>"),
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead",
),
message = "`{Self}` cannot be shared between threads safely",
2 changes: 1 addition & 1 deletion library/core/src/ops/index.rs
Original file line number Diff line number Diff line change
@@ -153,7 +153,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
),
on(
_Self = "std::string::String",
any(_Self = "alloc::string::String", _Self = "std::string::String"),
note = "you can use `.chars().nth()` or `.bytes().nth()`
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
),
45 changes: 36 additions & 9 deletions library/core/src/ops/try_trait.rs
Original file line number Diff line number Diff line change
@@ -226,8 +226,14 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
_Self = "std::result::Result<T, E>",
R = "std::option::Option<std::convert::Infallible>"
any(
_Self = "core::result::Result<T, E>",
_Self = "std::result::Result<T, E>",
),
any(
R = "core::option::Option<core::convert::Infallible>",
R = "std::option::Option<std::convert::Infallible>",
)
),
message = "the `?` operator can only be used on `Result`s, not `Option`s, \
in {ItemContext} that returns `Result`",
@@ -237,7 +243,10 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
_Self = "std::result::Result<T, E>",
any(
_Self = "core::result::Result<T, E>",
_Self = "std::result::Result<T, E>",
)
),
// There's a special error message in the trait selection code for
// `From` in `?`, so this is not shown for result-in-result errors,
@@ -250,8 +259,14 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
_Self = "std::option::Option<T>",
R = "std::result::Result<T, E>",
any(
_Self = "core::option::Option<T>",
_Self = "std::option::Option<T>",
),
any(
R = "core::result::Result<T, E>",
R = "std::result::Result<T, E>",
)
),
message = "the `?` operator can only be used on `Option`s, not `Result`s, \
in {ItemContext} that returns `Option`",
@@ -261,7 +276,10 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
_Self = "std::option::Option<T>",
any(
_Self = "core::option::Option<T>",
_Self = "std::option::Option<T>",
)
),
// `Option`-in-`Option` always works, as there's only one possible
// residual, so this can also be phrased strongly.
@@ -273,8 +291,14 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
_Self = "std::ops::ControlFlow<B, C>",
R = "std::ops::ControlFlow<B, C>",
any(
_Self = "core::ops::ControlFlow<B, C>",
_Self = "std::ops::ControlFlow<B, C>",
),
any(
R = "core::ops::ControlFlow<B, C>",
R = "std::ops::ControlFlow<B, C>",
)
),
message = "the `?` operator in {ItemContext} that returns `ControlFlow<B, _>` \
can only be used on other `ControlFlow<B, _>`s (with the same Break type)",
@@ -285,7 +309,10 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
_Self = "std::ops::ControlFlow<B, C>",
any(
_Self = "core::ops::ControlFlow<B, C>",
_Self = "std::ops::ControlFlow<B, C>",
)
// `R` is not a `ControlFlow`, as that case was matched previously
),
message = "the `?` operator can only be used on `ControlFlow`s \
5 changes: 4 additions & 1 deletion library/core/src/slice/index.rs
Original file line number Diff line number Diff line change
@@ -152,7 +152,10 @@ mod private_slice_index {
#[rustc_on_unimplemented(
on(T = "str", label = "string indices are ranges of `usize`",),
on(
all(any(T = "str", T = "&str", T = "std::string::String"), _Self = "{integer}"),
all(
any(T = "str", T = "&str", T = "alloc::string::String", T = "std::string::String"),
_Self = "{integer}"
),
note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
for more information, see chapter 8 in The Book: \
<https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
12 changes: 5 additions & 7 deletions library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
#![deny(unsafe_code)]

use crate::{Delimiter, Level, LineColumn, Spacing};
use crate::{Delimiter, Level, Spacing};
use std::fmt;
use std::hash::Hash;
use std::marker;
@@ -95,10 +95,10 @@ macro_rules! with_api {
fn parent($self: $S::Span) -> Option<$S::Span>;
fn source($self: $S::Span) -> $S::Span;
fn byte_range($self: $S::Span) -> Range<usize>;
fn start($self: $S::Span) -> LineColumn;
fn end($self: $S::Span) -> LineColumn;
fn before($self: $S::Span) -> $S::Span;
fn after($self: $S::Span) -> $S::Span;
fn start($self: $S::Span) -> $S::Span;
fn end($self: $S::Span) -> $S::Span;
fn line($self: $S::Span) -> usize;
fn column($self: $S::Span) -> usize;
fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
@@ -299,7 +299,6 @@ mark_noop! {
Delimiter,
LitKind,
Level,
LineColumn,
Spacing,
}

@@ -319,7 +318,6 @@ rpc_encode_decode!(
Help,
}
);
rpc_encode_decode!(struct LineColumn { line, column });
rpc_encode_decode!(
enum Spacing {
Alone,
71 changes: 18 additions & 53 deletions library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -43,7 +43,6 @@ mod diagnostic;
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
pub use diagnostic::{Diagnostic, Level, MultiSpan};

use std::cmp::Ordering;
use std::ops::{Range, RangeBounds};
use std::path::PathBuf;
use std::str::FromStr;
@@ -494,28 +493,32 @@ impl Span {
self.0.byte_range()
}

/// Gets the starting line/column in the source file for this span.
/// Creates an empty span pointing to directly before this span.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn start(&self) -> LineColumn {
self.0.start().add_1_to_column()
pub fn start(&self) -> Span {
Span(self.0.start())
}

/// Gets the ending line/column in the source file for this span.
/// Creates an empty span pointing to directly after this span.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn end(&self) -> LineColumn {
self.0.end().add_1_to_column()
pub fn end(&self) -> Span {
Span(self.0.end())
}

/// Creates an empty span pointing to directly before this span.
#[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
pub fn before(&self) -> Span {
Span(self.0.before())
/// The one-indexed line of the source file where the span starts.
///
/// To obtain the line of the span's end, use `span.end().line()`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn line(&self) -> usize {
self.0.line()
}

/// Creates an empty span pointing to directly after this span.
#[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
pub fn after(&self) -> Span {
Span(self.0.after())
/// The one-indexed column of the source file where the span starts.
///
/// To obtain the column of the span's end, use `span.end().column()`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn column(&self) -> usize {
self.0.column()
}

/// Creates a new span encompassing `self` and `other`.
@@ -586,44 +589,6 @@ impl fmt::Debug for Span {
}
}

/// A line-column pair representing the start or end of a `Span`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct LineColumn {
/// The 1-indexed line in the source file on which the span starts or ends (inclusive).
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub line: usize,
/// The 1-indexed column (number of bytes in UTF-8 encoding) in the source
/// file on which the span starts or ends (inclusive).
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub column: usize,
}

impl LineColumn {
fn add_1_to_column(self) -> Self {
LineColumn { line: self.line, column: self.column + 1 }
}
}

#[unstable(feature = "proc_macro_span", issue = "54725")]
impl !Send for LineColumn {}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl !Sync for LineColumn {}

#[unstable(feature = "proc_macro_span", issue = "54725")]
impl Ord for LineColumn {
fn cmp(&self, other: &Self) -> Ordering {
self.line.cmp(&other.line).then(self.column.cmp(&other.column))
}
}

#[unstable(feature = "proc_macro_span", issue = "54725")]
impl PartialOrd for LineColumn {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

/// The source file of a given `Span`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[derive(Clone)]
42 changes: 42 additions & 0 deletions library/std/src/f32.rs
Original file line number Diff line number Diff line change
@@ -960,4 +960,46 @@ impl f32 {
pub fn atanh(self) -> f32 {
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
}

/// Gamma function.
///
/// # Examples
///
/// ```
/// #![feature(float_gamma)]
/// let x = 5.0f32;
///
/// let abs_difference = (x.gamma() - 24.0).abs();
///
/// assert!(abs_difference <= f32::EPSILON);
/// ```
#[rustc_allow_incoherent_impl]
#[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_gamma", issue = "99842")]
#[inline]
pub fn gamma(self) -> f32 {
unsafe { cmath::tgammaf(self) }
}

/// Returns the natural logarithm of the gamma function.
///
/// # Examples
///
/// ```
/// #![feature(float_gamma)]
/// let x = 2.0f32;
///
/// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
///
/// assert!(abs_difference <= f32::EPSILON);
/// ```
#[rustc_allow_incoherent_impl]
#[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_gamma", issue = "99842")]
#[inline]
pub fn ln_gamma(self) -> (f32, i32) {
let mut signgamp: i32 = 0;
let x = unsafe { cmath::lgammaf_r(self, &mut signgamp) };
(x, signgamp)
}
}
31 changes: 31 additions & 0 deletions library/std/src/f32/tests.rs
Original file line number Diff line number Diff line change
@@ -652,6 +652,37 @@ fn test_atanh() {
assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
}

#[test]
fn test_gamma() {
assert_approx_eq!(1.0f32.gamma(), 1.0f32);
assert_approx_eq!(2.0f32.gamma(), 1.0f32);
assert_approx_eq!(3.0f32.gamma(), 2.0f32);
assert_approx_eq!(4.0f32.gamma(), 6.0f32);
assert_approx_eq!(5.0f32.gamma(), 24.0f32);
assert_approx_eq!(0.5f32.gamma(), consts::PI.sqrt());
assert_approx_eq!((-0.5f32).gamma(), -2.0 * consts::PI.sqrt());
assert_eq!(0.0f32.gamma(), f32::INFINITY);
assert_eq!((-0.0f32).gamma(), f32::NEG_INFINITY);
assert!((-1.0f32).gamma().is_nan());
assert!((-2.0f32).gamma().is_nan());
assert!(f32::NAN.gamma().is_nan());
assert!(f32::NEG_INFINITY.gamma().is_nan());
assert_eq!(f32::INFINITY.gamma(), f32::INFINITY);
assert_eq!(171.71f32.gamma(), f32::INFINITY);
}

#[test]
fn test_ln_gamma() {
assert_approx_eq!(1.0f32.ln_gamma().0, 0.0f32);
assert_eq!(1.0f32.ln_gamma().1, 1);
assert_approx_eq!(2.0f32.ln_gamma().0, 0.0f32);
assert_eq!(2.0f32.ln_gamma().1, 1);
assert_approx_eq!(3.0f32.ln_gamma().0, 2.0f32.ln());
assert_eq!(3.0f32.ln_gamma().1, 1);
assert_approx_eq!((-0.5f32).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
assert_eq!((-0.5f32).ln_gamma().1, -1);
}

#[test]
fn test_real_consts() {
use super::consts;
42 changes: 42 additions & 0 deletions library/std/src/f64.rs
Original file line number Diff line number Diff line change
@@ -986,4 +986,46 @@ impl f64 {
Self::NAN // log(-Inf) = NaN
}
}

/// Gamma function.
///
/// # Examples
///
/// ```
/// #![feature(float_gamma)]
/// let x = 5.0f64;
///
/// let abs_difference = (x.gamma() - 24.0).abs();
///
/// assert!(abs_difference <= f64::EPSILON);
/// ```
#[rustc_allow_incoherent_impl]
#[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_gamma", issue = "99842")]
#[inline]
pub fn gamma(self) -> f64 {
unsafe { cmath::tgamma(self) }
}

/// Returns the natural logarithm of the gamma function.
///
/// # Examples
///
/// ```
/// #![feature(float_gamma)]
/// let x = 2.0f64;
///
/// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
///
/// assert!(abs_difference <= f64::EPSILON);
/// ```
#[rustc_allow_incoherent_impl]
#[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_gamma", issue = "99842")]
#[inline]
pub fn ln_gamma(self) -> (f64, i32) {
let mut signgamp: i32 = 0;
let x = unsafe { cmath::lgamma_r(self, &mut signgamp) };
(x, signgamp)
}
}
31 changes: 31 additions & 0 deletions library/std/src/f64/tests.rs
Original file line number Diff line number Diff line change
@@ -635,6 +635,37 @@ fn test_atanh() {
assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
}

#[test]
fn test_gamma() {
assert_approx_eq!(1.0f64.gamma(), 1.0f64);
assert_approx_eq!(2.0f64.gamma(), 1.0f64);
assert_approx_eq!(3.0f64.gamma(), 2.0f64);
assert_approx_eq!(4.0f64.gamma(), 6.0f64);
assert_approx_eq!(5.0f64.gamma(), 24.0f64);
assert_approx_eq!(0.5f64.gamma(), consts::PI.sqrt());
assert_approx_eq!((-0.5f64).gamma(), -2.0 * consts::PI.sqrt());
assert_eq!(0.0f64.gamma(), f64::INFINITY);
assert_eq!((-0.0f64).gamma(), f64::NEG_INFINITY);
assert!((-1.0f64).gamma().is_nan());
assert!((-2.0f64).gamma().is_nan());
assert!(f64::NAN.gamma().is_nan());
assert!(f64::NEG_INFINITY.gamma().is_nan());
assert_eq!(f64::INFINITY.gamma(), f64::INFINITY);
assert_eq!(171.71f64.gamma(), f64::INFINITY);
}

#[test]
fn test_ln_gamma() {
assert_approx_eq!(1.0f64.ln_gamma().0, 0.0f64);
assert_eq!(1.0f64.ln_gamma().1, 1);
assert_approx_eq!(2.0f64.ln_gamma().0, 0.0f64);
assert_eq!(2.0f64.ln_gamma().1, 1);
assert_approx_eq!(3.0f64.ln_gamma().0, 2.0f64.ln());
assert_eq!(3.0f64.ln_gamma().1, 1);
assert_approx_eq!((-0.5f64).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
assert_eq!((-0.5f64).ln_gamma().1, -1);
}

#[test]
fn test_real_consts() {
use super::consts;
97 changes: 65 additions & 32 deletions library/std/src/fs.rs
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ use crate::fmt;
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
use crate::path::{Path, PathBuf};
use crate::sealed::Sealed;
use crate::sync::Arc;
use crate::sys::fs as fs_imp;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
use crate::time::SystemTime;
@@ -743,7 +744,7 @@ fn buffer_capacity_required(mut file: &File) -> Option<usize> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for File {
impl Read for &File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
@@ -776,7 +777,7 @@ impl Read for File {
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for File {
impl Write for &File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
@@ -795,67 +796,99 @@ impl Write for File {
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Seek for File {
impl Seek for &File {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.inner.seek(pos)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for &File {
impl Read for File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
(&*self).read(buf)
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
(&*self).read_vectored(bufs)
}

fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
self.inner.read_buf(cursor)
(&*self).read_buf(cursor)
}
#[inline]
fn is_read_vectored(&self) -> bool {
(&&*self).is_read_vectored()
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
(&*self).read_to_end(buf)
}
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
(&*self).read_to_string(buf)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
(&*self).write(buf)
}
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
(&*self).write_vectored(bufs)
}
#[inline]
fn is_write_vectored(&self) -> bool {
(&&*self).is_write_vectored()
}
fn flush(&mut self) -> io::Result<()> {
(&*self).flush()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Seek for File {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
(&*self).seek(pos)
}
}

#[stable(feature = "io_traits_arc", since = "CURRENT_RUSTC_VERSION")]
impl Read for Arc<File> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(&**self).read(buf)
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
self.inner.read_vectored(bufs)
(&**self).read_vectored(bufs)
}
fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
(&**self).read_buf(cursor)
}

#[inline]
fn is_read_vectored(&self) -> bool {
self.inner.is_read_vectored()
(&**self).is_read_vectored()
}

// Reserves space in the buffer based on the file size when available.
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
let size = buffer_capacity_required(self);
buf.reserve(size.unwrap_or(0));
io::default_read_to_end(self, buf, size)
(&**self).read_to_end(buf)
}

// Reserves space in the buffer based on the file size when available.
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
let size = buffer_capacity_required(self);
buf.reserve(size.unwrap_or(0));
io::default_read_to_string(self, buf, size)
(&**self).read_to_string(buf)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for &File {
#[stable(feature = "io_traits_arc", since = "CURRENT_RUSTC_VERSION")]
impl Write for Arc<File> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
(&**self).write(buf)
}

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
self.inner.write_vectored(bufs)
(&**self).write_vectored(bufs)
}

#[inline]
fn is_write_vectored(&self) -> bool {
self.inner.is_write_vectored()
(&**self).is_write_vectored()
}

fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
(&**self).flush()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Seek for &File {
#[stable(feature = "io_traits_arc", since = "CURRENT_RUSTC_VERSION")]
impl Seek for Arc<File> {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.inner.seek(pos)
(&**self).seek(pos)
}
}

1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -287,6 +287,7 @@
#![feature(exact_size_is_empty)]
#![feature(exclusive_wrapper)]
#![feature(extend_one)]
#![feature(float_gamma)]
#![feature(float_minimum_maximum)]
#![feature(float_next_up_down)]
#![feature(hasher_prefixfree_extras)]
4 changes: 4 additions & 0 deletions library/std/src/sys/unix/cmath.rs
Original file line number Diff line number Diff line change
@@ -30,4 +30,8 @@ extern "C" {
pub fn tanf(n: f32) -> f32;
pub fn tanh(n: f64) -> f64;
pub fn tanhf(n: f32) -> f32;
pub fn tgamma(n: f64) -> f64;
pub fn tgammaf(n: f32) -> f32;
pub fn lgamma_r(n: f64, s: &mut i32) -> f64;
pub fn lgammaf_r(n: f32, s: &mut i32) -> f32;
}
6 changes: 5 additions & 1 deletion library/std/src/sys/windows/cmath.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![cfg(not(test))]

use libc::{c_double, c_float};
use libc::{c_double, c_float, c_int};

extern "C" {
pub fn acos(n: c_double) -> c_double;
@@ -23,6 +23,10 @@ extern "C" {
pub fn sinh(n: c_double) -> c_double;
pub fn tan(n: c_double) -> c_double;
pub fn tanh(n: c_double) -> c_double;
pub fn tgamma(n: c_double) -> c_double;
pub fn tgammaf(n: c_float) -> c_float;
pub fn lgamma_r(n: c_double, s: &mut c_int) -> c_double;
pub fn lgammaf_r(n: c_float, s: &mut c_int) -> c_float;
}

pub use self::shims::*;
2 changes: 1 addition & 1 deletion library/test/src/console.rs
Original file line number Diff line number Diff line change
@@ -199,7 +199,7 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Res
let TestDescAndFn { desc, testfn } = test;

let fntype = match testfn {
StaticTestFn(..) | DynTestFn(..) => {
StaticTestFn(..) | DynTestFn(..) | StaticBenchAsTestFn(..) | DynBenchAsTestFn(..) => {
st.tests += 1;
"test"
}
206 changes: 89 additions & 117 deletions library/test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -92,6 +92,7 @@ use time::TestExecTime;
const ERROR_EXIT_CODE: i32 = 101;

const SECONDARY_TEST_INVOKER_VAR: &str = "__RUST_TEST_INVOKE";
const SECONDARY_TEST_BENCH_BENCHMARKS_VAR: &str = "__RUST_TEST_BENCH_BENCHMARKS";

// The default console test runner. It accepts the command line
// arguments and a vector of test_descs.
@@ -171,18 +172,32 @@ pub fn test_main_static_abort(tests: &[&TestDescAndFn]) {
// will then exit the process.
if let Ok(name) = env::var(SECONDARY_TEST_INVOKER_VAR) {
env::remove_var(SECONDARY_TEST_INVOKER_VAR);

// Convert benchmarks to tests if we're not benchmarking.
let mut tests = tests.iter().map(make_owned_test).collect::<Vec<_>>();
if env::var(SECONDARY_TEST_BENCH_BENCHMARKS_VAR).is_ok() {
env::remove_var(SECONDARY_TEST_BENCH_BENCHMARKS_VAR);
} else {
tests = convert_benchmarks_to_tests(tests);
};

let test = tests
.iter()
.into_iter()
.filter(|test| test.desc.name.as_slice() == name)
.map(make_owned_test)
.next()
.unwrap_or_else(|| panic!("couldn't find a test with the provided name '{name}'"));
let TestDescAndFn { desc, testfn } = test;
let testfn = match testfn {
StaticTestFn(f) => f,
_ => panic!("only static tests are supported"),
};
run_test_in_spawned_subprocess(desc, Box::new(testfn));
match testfn.into_runnable() {
Runnable::Test(runnable_test) => {
if runnable_test.is_dynamic() {
panic!("only static tests are supported");
}
run_test_in_spawned_subprocess(desc, runnable_test);
}
Runnable::Bench(_) => {
panic!("benchmarks should not be executed into child processes")
}
}
}

let args = env::args().collect::<Vec<_>>();
@@ -234,16 +249,6 @@ impl FilteredTests {
self.tests.push((TestId(self.next_id), test));
self.next_id += 1;
}
fn add_bench_as_test(
&mut self,
desc: TestDesc,
benchfn: impl Fn(&mut Bencher) -> Result<(), String> + Send + 'static,
) {
let testfn = DynTestFn(Box::new(move || {
bench::run_once(|b| __rust_begin_short_backtrace(|| benchfn(b)))
}));
self.add_test(desc, testfn);
}
fn total_len(&self) -> usize {
self.tests.len() + self.benches.len()
}
@@ -301,14 +306,14 @@ where
if opts.bench_benchmarks {
filtered.add_bench(desc, DynBenchFn(benchfn));
} else {
filtered.add_bench_as_test(desc, benchfn);
filtered.add_test(desc, DynBenchAsTestFn(benchfn));
}
}
StaticBenchFn(benchfn) => {
if opts.bench_benchmarks {
filtered.add_bench(desc, StaticBenchFn(benchfn));
} else {
filtered.add_bench_as_test(desc, benchfn);
filtered.add_test(desc, StaticBenchAsTestFn(benchfn));
}
}
testfn => {
@@ -519,12 +524,8 @@ pub fn convert_benchmarks_to_tests(tests: Vec<TestDescAndFn>) -> Vec<TestDescAnd
.into_iter()
.map(|x| {
let testfn = match x.testfn {
DynBenchFn(benchfn) => DynTestFn(Box::new(move || {
bench::run_once(|b| __rust_begin_short_backtrace(|| benchfn(b)))
})),
StaticBenchFn(benchfn) => DynTestFn(Box::new(move || {
bench::run_once(|b| __rust_begin_short_backtrace(|| benchfn(b)))
})),
DynBenchFn(benchfn) => DynBenchAsTestFn(benchfn),
StaticBenchFn(benchfn) => StaticBenchAsTestFn(benchfn),
f => f,
};
TestDescAndFn { desc: x.desc, testfn }
@@ -553,99 +554,69 @@ pub fn run_test(
return None;
}

struct TestRunOpts {
pub strategy: RunStrategy,
pub nocapture: bool,
pub time: Option<time::TestTimeOptions>,
}
match testfn.into_runnable() {
Runnable::Test(runnable_test) => {
if runnable_test.is_dynamic() {
match strategy {
RunStrategy::InProcess => (),
_ => panic!("Cannot run dynamic test fn out-of-process"),
};
}

fn run_test_inner(
id: TestId,
desc: TestDesc,
monitor_ch: Sender<CompletedTest>,
testfn: Box<dyn FnOnce() -> Result<(), String> + Send>,
opts: TestRunOpts,
) -> Option<thread::JoinHandle<()>> {
let name = desc.name.clone();

let runtest = move || match opts.strategy {
RunStrategy::InProcess => run_test_in_process(
id,
desc,
opts.nocapture,
opts.time.is_some(),
testfn,
monitor_ch,
opts.time,
),
RunStrategy::SpawnPrimary => spawn_test_subprocess(
id,
desc,
opts.nocapture,
opts.time.is_some(),
monitor_ch,
opts.time,
),
};
let name = desc.name.clone();
let nocapture = opts.nocapture;
let time_options = opts.time_options;
let bench_benchmarks = opts.bench_benchmarks;

let runtest = move || match strategy {
RunStrategy::InProcess => run_test_in_process(
id,
desc,
nocapture,
time_options.is_some(),
runnable_test,
monitor_ch,
time_options,
),
RunStrategy::SpawnPrimary => spawn_test_subprocess(
id,
desc,
nocapture,
time_options.is_some(),
monitor_ch,
time_options,
bench_benchmarks,
),
};

// If the platform is single-threaded we're just going to run
// the test synchronously, regardless of the concurrency
// level.
let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_family = "wasm");
if supports_threads {
let cfg = thread::Builder::new().name(name.as_slice().to_owned());
let mut runtest = Arc::new(Mutex::new(Some(runtest)));
let runtest2 = runtest.clone();
match cfg.spawn(move || runtest2.lock().unwrap().take().unwrap()()) {
Ok(handle) => Some(handle),
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
// `ErrorKind::WouldBlock` means hitting the thread limit on some
// platforms, so run the test synchronously here instead.
Arc::get_mut(&mut runtest).unwrap().get_mut().unwrap().take().unwrap()();
None
// If the platform is single-threaded we're just going to run
// the test synchronously, regardless of the concurrency
// level.
let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_family = "wasm");
if supports_threads {
let cfg = thread::Builder::new().name(name.as_slice().to_owned());
let mut runtest = Arc::new(Mutex::new(Some(runtest)));
let runtest2 = runtest.clone();
match cfg.spawn(move || runtest2.lock().unwrap().take().unwrap()()) {
Ok(handle) => Some(handle),
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
// `ErrorKind::WouldBlock` means hitting the thread limit on some
// platforms, so run the test synchronously here instead.
Arc::get_mut(&mut runtest).unwrap().get_mut().unwrap().take().unwrap()();
None
}
Err(e) => panic!("failed to spawn thread to run test: {e}"),
}
Err(e) => panic!("failed to spawn thread to run test: {e}"),
} else {
runtest();
None
}
} else {
runtest();
None
}
}

let test_run_opts =
TestRunOpts { strategy, nocapture: opts.nocapture, time: opts.time_options };

match testfn {
DynBenchFn(benchfn) => {
Runnable::Bench(runnable_bench) => {
// Benchmarks aren't expected to panic, so we run them all in-process.
crate::bench::benchmark(id, desc, monitor_ch, opts.nocapture, benchfn);
runnable_bench.run(id, &desc, &monitor_ch, opts.nocapture);
None
}
StaticBenchFn(benchfn) => {
// Benchmarks aren't expected to panic, so we run them all in-process.
crate::bench::benchmark(id, desc, monitor_ch, opts.nocapture, benchfn);
None
}
DynTestFn(f) => {
match strategy {
RunStrategy::InProcess => (),
_ => panic!("Cannot run dynamic test fn out-of-process"),
};
run_test_inner(
id,
desc,
monitor_ch,
Box::new(move || __rust_begin_short_backtrace(f)),
test_run_opts,
)
}
StaticTestFn(f) => run_test_inner(
id,
desc,
monitor_ch,
Box::new(move || __rust_begin_short_backtrace(f)),
test_run_opts,
),
}
}

@@ -663,7 +634,7 @@ fn run_test_in_process(
desc: TestDesc,
nocapture: bool,
report_time: bool,
testfn: Box<dyn FnOnce() -> Result<(), String> + Send>,
runnable_test: RunnableTest,
monitor_ch: Sender<CompletedTest>,
time_opts: Option<time::TestTimeOptions>,
) {
@@ -675,7 +646,7 @@ fn run_test_in_process(
}

let start = report_time.then(Instant::now);
let result = fold_err(catch_unwind(AssertUnwindSafe(testfn)));
let result = fold_err(catch_unwind(AssertUnwindSafe(|| runnable_test.run())));
let exec_time = start.map(|start| {
let duration = start.elapsed();
TestExecTime(duration)
@@ -712,13 +683,17 @@ fn spawn_test_subprocess(
report_time: bool,
monitor_ch: Sender<CompletedTest>,
time_opts: Option<time::TestTimeOptions>,
bench_benchmarks: bool,
) {
let (result, test_output, exec_time) = (|| {
let args = env::args().collect::<Vec<_>>();
let current_exe = &args[0];

let mut command = Command::new(current_exe);
command.env(SECONDARY_TEST_INVOKER_VAR, desc.name.as_slice());
if bench_benchmarks {
command.env(SECONDARY_TEST_BENCH_BENCHMARKS_VAR, "1");
}
if nocapture {
command.stdout(process::Stdio::inherit());
command.stderr(process::Stdio::inherit());
@@ -760,10 +735,7 @@ fn spawn_test_subprocess(
monitor_ch.send(message).unwrap();
}

fn run_test_in_spawned_subprocess(
desc: TestDesc,
testfn: Box<dyn FnOnce() -> Result<(), String> + Send>,
) -> ! {
fn run_test_in_spawned_subprocess(desc: TestDesc, runnable_test: RunnableTest) -> ! {
let builtin_panic_hook = panic::take_hook();
let record_result = Arc::new(move |panic_info: Option<&'_ PanicInfo<'_>>| {
let test_result = match panic_info {
@@ -789,7 +761,7 @@ fn run_test_in_spawned_subprocess(
});
let record_result2 = record_result.clone();
panic::set_hook(Box::new(move |info| record_result2(Some(info))));
if let Err(message) = testfn() {
if let Err(message) = runnable_test.run() {
panic!("{}", message);
}
record_result(None);
80 changes: 80 additions & 0 deletions library/test/src/types.rs
Original file line number Diff line number Diff line change
@@ -2,8 +2,11 @@
use std::borrow::Cow;
use std::fmt;
use std::sync::mpsc::Sender;

use super::__rust_begin_short_backtrace;
use super::bench::Bencher;
use super::event::CompletedTest;
use super::options;

pub use NamePadding::*;
@@ -82,17 +85,32 @@ impl fmt::Display for TestName {
pub enum TestFn {
StaticTestFn(fn() -> Result<(), String>),
StaticBenchFn(fn(&mut Bencher) -> Result<(), String>),
StaticBenchAsTestFn(fn(&mut Bencher) -> Result<(), String>),
DynTestFn(Box<dyn FnOnce() -> Result<(), String> + Send>),
DynBenchFn(Box<dyn Fn(&mut Bencher) -> Result<(), String> + Send>),
DynBenchAsTestFn(Box<dyn Fn(&mut Bencher) -> Result<(), String> + Send>),
}

impl TestFn {
pub fn padding(&self) -> NamePadding {
match *self {
StaticTestFn(..) => PadNone,
StaticBenchFn(..) => PadOnRight,
StaticBenchAsTestFn(..) => PadNone,
DynTestFn(..) => PadNone,
DynBenchFn(..) => PadOnRight,
DynBenchAsTestFn(..) => PadNone,
}
}

pub(crate) fn into_runnable(self) -> Runnable {
match self {
StaticTestFn(f) => Runnable::Test(RunnableTest::Static(f)),
StaticBenchFn(f) => Runnable::Bench(RunnableBench::Static(f)),
StaticBenchAsTestFn(f) => Runnable::Test(RunnableTest::StaticBenchAsTest(f)),
DynTestFn(f) => Runnable::Test(RunnableTest::Dynamic(f)),
DynBenchFn(f) => Runnable::Bench(RunnableBench::Dynamic(f)),
DynBenchAsTestFn(f) => Runnable::Test(RunnableTest::DynamicBenchAsTest(f)),
}
}
}
@@ -102,12 +120,74 @@ impl fmt::Debug for TestFn {
f.write_str(match *self {
StaticTestFn(..) => "StaticTestFn(..)",
StaticBenchFn(..) => "StaticBenchFn(..)",
StaticBenchAsTestFn(..) => "StaticBenchAsTestFn(..)",
DynTestFn(..) => "DynTestFn(..)",
DynBenchFn(..) => "DynBenchFn(..)",
DynBenchAsTestFn(..) => "DynBenchAsTestFn(..)",
})
}
}

pub(crate) enum Runnable {
Test(RunnableTest),
Bench(RunnableBench),
}

pub(crate) enum RunnableTest {
Static(fn() -> Result<(), String>),
Dynamic(Box<dyn FnOnce() -> Result<(), String> + Send>),
StaticBenchAsTest(fn(&mut Bencher) -> Result<(), String>),
DynamicBenchAsTest(Box<dyn Fn(&mut Bencher) -> Result<(), String> + Send>),
}

impl RunnableTest {
pub(crate) fn run(self) -> Result<(), String> {
match self {
RunnableTest::Static(f) => __rust_begin_short_backtrace(f),
RunnableTest::Dynamic(f) => __rust_begin_short_backtrace(f),
RunnableTest::StaticBenchAsTest(f) => {
crate::bench::run_once(|b| __rust_begin_short_backtrace(|| f(b)))
}
RunnableTest::DynamicBenchAsTest(f) => {
crate::bench::run_once(|b| __rust_begin_short_backtrace(|| f(b)))
}
}
}

pub(crate) fn is_dynamic(&self) -> bool {
match self {
RunnableTest::Static(_) => false,
RunnableTest::StaticBenchAsTest(_) => false,
RunnableTest::Dynamic(_) => true,
RunnableTest::DynamicBenchAsTest(_) => true,
}
}
}

pub(crate) enum RunnableBench {
Static(fn(&mut Bencher) -> Result<(), String>),
Dynamic(Box<dyn Fn(&mut Bencher) -> Result<(), String> + Send>),
}

impl RunnableBench {
pub(crate) fn run(
self,
id: TestId,
desc: &TestDesc,
monitor_ch: &Sender<CompletedTest>,
nocapture: bool,
) {
match self {
RunnableBench::Static(f) => {
crate::bench::benchmark(id, desc.clone(), monitor_ch.clone(), nocapture, f)
}
RunnableBench::Dynamic(f) => {
crate::bench::benchmark(id, desc.clone(), monitor_ch.clone(), nocapture, f)
}
}
}
}

// A unique integer associated with each test.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct TestId(pub usize);
4 changes: 2 additions & 2 deletions src/bootstrap/Cargo.lock
2 changes: 1 addition & 1 deletion src/bootstrap/download-ci-llvm-stamp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Change this file to make users of the `download-ci-llvm` configuration download
a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.

Last change is for: https://github.com/rust-lang/rust/pull/96971
Last change is for: https://github.com/rust-lang/rust/pull/112931
2 changes: 1 addition & 1 deletion src/bootstrap/llvm.rs
Original file line number Diff line number Diff line change
@@ -352,7 +352,7 @@ impl Step for Llvm {
// Disable zstd to avoid a dependency on libzstd.so.
cfg.define("LLVM_ENABLE_ZSTD", "OFF");

if target != "aarch64-apple-darwin" && !target.contains("windows") {
if !target.contains("windows") {
cfg.define("LLVM_ENABLE_ZLIB", "ON");
} else {
cfg.define("LLVM_ENABLE_ZLIB", "OFF");
3 changes: 1 addition & 2 deletions src/librustdoc/html/templates/page.html
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@
{% endfor %}
></script> {# #}
{% endif %}
<div id="rustdoc-vars" {#+ #}
<meta id="rustdoc-vars" {#+ #}
data-root-path="{{page.root_path|safe}}" {#+ #}
data-static-root-path="{{static_root_path|safe}}" {#+ #}
data-current-crate="{{layout.krate}}" {#+ #}
@@ -39,7 +39,6 @@
data-theme-dark-css="{{files.theme_dark_css}}" {#+ #}
data-theme-ayu-css="{{files.theme_ayu_css}}" {#+ #}
> {# #}
</div> {# #}
<script src="{{static_root_path|safe}}{{files.storage_js}}"></script> {# #}
{% if page.css_class.contains("crate") %}
<script defer src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {# #}
4 changes: 2 additions & 2 deletions src/tools/miri/Cargo.lock
4 changes: 2 additions & 2 deletions src/tools/miri/cargo-miri/Cargo.lock
4 changes: 2 additions & 2 deletions src/tools/miri/test-cargo-miri/Cargo.lock
4 changes: 2 additions & 2 deletions src/tools/miri/test_dependencies/Cargo.lock
4 changes: 2 additions & 2 deletions src/tools/rust-analyzer/Cargo.lock
27 changes: 13 additions & 14 deletions src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
Original file line number Diff line number Diff line change
@@ -8,10 +8,7 @@
//!
//! FIXME: No span and source file information is implemented yet
use proc_macro::{
bridge::{self, server},
LineColumn,
};
use proc_macro::bridge::{self, server};

mod token_stream;
pub use token_stream::TokenStream;
@@ -304,14 +301,6 @@ impl server::Span for RustAnalyzer {
// FIXME handle span
Range { start: 0, end: 0 }
}
fn start(&mut self, _span: Self::Span) -> LineColumn {
// FIXME handle span
LineColumn { line: 0, column: 0 }
}
fn end(&mut self, _span: Self::Span) -> LineColumn {
// FIXME handle span
LineColumn { line: 0, column: 0 }
}
fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option<Self::Span> {
// Just return the first span again, because some macros will unwrap the result.
Some(first)
@@ -330,13 +319,23 @@ impl server::Span for RustAnalyzer {
tt::TokenId::unspecified()
}

fn after(&mut self, _self_: Self::Span) -> Self::Span {
fn end(&mut self, _self_: Self::Span) -> Self::Span {
tt::TokenId::unspecified()
}

fn before(&mut self, _self_: Self::Span) -> Self::Span {
fn start(&mut self, _self_: Self::Span) -> Self::Span {
tt::TokenId::unspecified()
}

fn line(&mut self, _span: Self::Span) -> usize {
// FIXME handle line
0
}

fn column(&mut self, _span: Self::Span) -> usize {
// FIXME handle column
0
}
}

impl server::Symbol for RustAnalyzer {
2 changes: 1 addition & 1 deletion tests/codegen/avr/avr-func-addrspace.rs
Original file line number Diff line number Diff line change
@@ -116,7 +116,7 @@ pub enum Either<T, U> { A(T), B(U) }
// with the `ptr` field representing both `&i32` and `fn()` depending on the variant.
// This is incorrect, because `fn()` should be `ptr addrspace(1)`, not `ptr`.

// CHECK: define{{.+}}void @should_not_combine_addrspace({{.+\*|ptr}}{{.+}}sret{{.+}}%0, {{.+\*|ptr}}{{.+}}%x)
// CHECK: define{{.+}}void @should_not_combine_addrspace({{.+\*|ptr}}{{.+}}sret{{.+}}%_0, {{.+\*|ptr}}{{.+}}%x)
#[no_mangle]
#[inline(never)]
pub fn should_not_combine_addrspace(x: Either<&i32, fn()>) -> Either<&i32, fn()> {
5 changes: 3 additions & 2 deletions tests/codegen/consts.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// compile-flags: -C no-prepopulate-passes
// min-llvm-version: 15.0 (for opaque pointers)

#![crate_type = "lib"]

@@ -42,14 +43,14 @@ pub fn inline_enum_const() -> E<i8, i16> {
#[no_mangle]
pub fn low_align_const() -> E<i16, [i16; 3]> {
// Check that low_align_const and high_align_const use the same constant
// CHECK: memcpy.{{.+}}({{i8\*|ptr}} align 2 %{{[0-9]+}}, {{i8\*|ptr}} align 2 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false)
// CHECK: memcpy.{{.+}}(ptr align 2 %_0, ptr align 2 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false)
*&E::A(0)
}

// CHECK-LABEL: @high_align_const
#[no_mangle]
pub fn high_align_const() -> E<i16, i32> {
// Check that low_align_const and high_align_const use the same constant
// CHECK: memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false)
// CHECK: memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false)
*&E::A(0)
}
2 changes: 1 addition & 1 deletion tests/codegen/enum-match.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ pub enum Enum0 {
// CHECK-NEXT: start:
// CHECK-NEXT: %1 = icmp eq i8 %0, 2
// CHECK-NEXT: %2 = and i8 %0, 1
// CHECK-NEXT: %.0 = select i1 %1, i8 13, i8 %2
// CHECK-NEXT: %_0.0 = select i1 %1, i8 13, i8 %2
#[no_mangle]
pub fn match0(e: Enum0) -> u8 {
use Enum0::*;
4 changes: 2 additions & 2 deletions tests/codegen/fewer-names.rs
Original file line number Diff line number Diff line change
@@ -13,8 +13,8 @@ pub fn sum(x: u32, y: u32) -> u32 {

// NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y)
// NO-NEXT: start:
// NO-NEXT: %0 = add i32 %y, %x
// NO-NEXT: ret i32 %0
// NO-NEXT: %z = add i32 %y, %x
// NO-NEXT: ret i32 %z
let z = x + y;
z
}
4 changes: 2 additions & 2 deletions tests/codegen/function-arguments-noopt.rs
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ pub fn borrow_call(x: &i32, f: fn(&i32) -> &i32) -> &i32 {
f(x)
}

// CHECK: void @struct_({{%S\*|ptr}} sret(%S){{( %0)?}}, {{%S\*|ptr}} %x)
// CHECK: void @struct_({{%S\*|ptr}} sret(%S){{( %_0)?}}, {{%S\*|ptr}} %x)
#[no_mangle]
pub fn struct_(x: S) -> S {
x
@@ -51,7 +51,7 @@ pub fn struct_(x: S) -> S {
// CHECK-LABEL: @struct_call
#[no_mangle]
pub fn struct_call(x: S, f: fn(S) -> S) -> S {
// CHECK: call void %f({{%S\*|ptr}} sret(%S){{( %0)?}}, {{%S\*|ptr}} %{{.+}})
// CHECK: call void %f({{%S\*|ptr}} sret(%S){{( %_0)?}}, {{%S\*|ptr}} %{{.+}})
f(x)
}

2 changes: 1 addition & 1 deletion tests/codegen/function-arguments.rs
Original file line number Diff line number Diff line change
@@ -188,7 +188,7 @@ pub fn notunpin_box(x: Box<NotUnpin>) -> Box<NotUnpin> {
x
}

// CHECK: @struct_return({{%S\*|ptr}} noalias nocapture noundef sret(%S) dereferenceable(32){{( %0)?}})
// CHECK: @struct_return({{%S\*|ptr}} noalias nocapture noundef sret(%S) dereferenceable(32){{( %_0)?}})
#[no_mangle]
pub fn struct_return() -> S {
S {
16 changes: 8 additions & 8 deletions tests/codegen/intrinsics/transmute-niched.rs
Original file line number Diff line number Diff line change
@@ -169,16 +169,16 @@ pub unsafe fn check_bool_from_ordering(x: std::cmp::Ordering) -> bool {
// CHECK-LABEL: @check_bool_to_ordering(
#[no_mangle]
pub unsafe fn check_bool_to_ordering(x: bool) -> std::cmp::Ordering {
// CHECK: %0 = zext i1 %x to i8
// OPT: %1 = icmp ule i8 %0, 1
// OPT: call void @llvm.assume(i1 %1)
// OPT: %2 = icmp uge i8 %0, -1
// OPT: %3 = icmp ule i8 %0, 1
// OPT: %4 = or i1 %2, %3
// OPT: call void @llvm.assume(i1 %4)
// CHECK: %_0 = zext i1 %x to i8
// OPT: %0 = icmp ule i8 %_0, 1
// OPT: call void @llvm.assume(i1 %0)
// OPT: %1 = icmp uge i8 %_0, -1
// OPT: %2 = icmp ule i8 %_0, 1
// OPT: %3 = or i1 %1, %2
// OPT: call void @llvm.assume(i1 %3)
// DBG-NOT: icmp
// DBG-NOT: assume
// CHECK: ret i8 %0
// CHECK: ret i8 %_0

transmute(x)
}
12 changes: 6 additions & 6 deletions tests/codegen/intrinsics/transmute-x64.rs
Original file line number Diff line number Diff line change
@@ -11,25 +11,25 @@ use std::mem::transmute;
#[no_mangle]
pub unsafe fn check_sse_float_to_int(x: __m128) -> __m128i {
// CHECK-NOT: alloca
// CHECK: %1 = load <4 x float>, ptr %x, align 16
// CHECK: store <4 x float> %1, ptr %0, align 16
// CHECK: %0 = load <4 x float>, ptr %x, align 16
// CHECK: store <4 x float> %0, ptr %_0, align 16
transmute(x)
}

// CHECK-LABEL: @check_sse_pair_to_avx(
#[no_mangle]
pub unsafe fn check_sse_pair_to_avx(x: (__m128i, __m128i)) -> __m256i {
// CHECK-NOT: alloca
// CHECK: %1 = load <4 x i64>, ptr %x, align 16
// CHECK: store <4 x i64> %1, ptr %0, align 32
// CHECK: %0 = load <4 x i64>, ptr %x, align 16
// CHECK: store <4 x i64> %0, ptr %_0, align 32
transmute(x)
}

// CHECK-LABEL: @check_sse_pair_from_avx(
#[no_mangle]
pub unsafe fn check_sse_pair_from_avx(x: __m256i) -> (__m128i, __m128i) {
// CHECK-NOT: alloca
// CHECK: %1 = load <4 x i64>, ptr %x, align 32
// CHECK: store <4 x i64> %1, ptr %0, align 16
// CHECK: %0 = load <4 x i64>, ptr %x, align 32
// CHECK: store <4 x i64> %0, ptr %_0, align 16
transmute(x)
}
90 changes: 43 additions & 47 deletions tests/codegen/intrinsics/transmute.rs
Original file line number Diff line number Diff line change
@@ -8,8 +8,8 @@
#![feature(inline_const)]
#![allow(unreachable_code)]

use std::mem::MaybeUninit;
use std::intrinsics::{transmute, transmute_unchecked};
use std::mem::MaybeUninit;

// Some of these need custom MIR to not get removed by MIR optimizations.
use std::intrinsics::mir::*;
@@ -63,7 +63,7 @@ pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] {
// CHECK-NOT: trap
// CHECK: call void @llvm.trap
// CHECK-NOT: trap
mir!{
mir! {
{
RET = CastTransmute(x);
Return()
@@ -78,7 +78,7 @@ pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] {
// CHECK-NOT: trap
// CHECK: call void @llvm.trap
// CHECK-NOT: trap
mir!{
mir! {
{
RET = CastTransmute(x);
Return()
@@ -93,7 +93,7 @@ pub unsafe fn check_to_uninhabited(x: u16) {
// CHECK-NOT: trap
// CHECK: call void @llvm.trap
// CHECK-NOT: trap
mir!{
mir! {
let temp: BigNever;
{
temp = CastTransmute(x);
@@ -107,7 +107,7 @@ pub unsafe fn check_to_uninhabited(x: u16) {
#[custom_mir(dialect = "runtime", phase = "optimized")]
pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 {
// CHECK: ret i16 poison
mir!{
mir! {
{
RET = CastTransmute(x);
Return()
@@ -122,9 +122,7 @@ pub unsafe fn check_intermediate_passthrough(x: u32) -> i32 {
// CHECK: %[[TMP:.+]] = add i32 1, %x
// CHECK: %[[RET:.+]] = add i32 %[[TMP]], 1
// CHECK: ret i32 %[[RET]]
unsafe {
transmute::<u32, i32>(1 + x) + 1
}
unsafe { transmute::<u32, i32>(1 + x) + 1 }
}

// CHECK-LABEL: @check_nop_pair(
@@ -134,9 +132,7 @@ pub unsafe fn check_nop_pair(x: (u8, i8)) -> (i8, u8) {
// CHECK: %0 = insertvalue { i8, i8 } poison, i8 %x.0, 0
// CHECK: %1 = insertvalue { i8, i8 } %0, i8 %x.1, 1
// CHECK: ret { i8, i8 } %1
unsafe {
transmute(x)
}
unsafe { transmute(x) }
}

// CHECK-LABEL: @check_to_newtype(
@@ -168,9 +164,9 @@ pub unsafe fn check_aggregate_to_bool(x: Aggregate8) -> bool {
// CHECK-LABEL: @check_aggregate_from_bool(
#[no_mangle]
pub unsafe fn check_aggregate_from_bool(x: bool) -> Aggregate8 {
// CHECK: %0 = alloca %Aggregate8, align 1
// CHECK: %_0 = alloca %Aggregate8, align 1
// CHECK: %[[BYTE:.+]] = zext i1 %x to i8
// CHECK: store i8 %[[BYTE]], ptr %0, align 1
// CHECK: store i8 %[[BYTE]], ptr %_0, align 1
transmute(x)
}

@@ -195,8 +191,8 @@ pub unsafe fn check_byte_from_bool(x: bool) -> u8 {
// CHECK-LABEL: @check_to_pair(
#[no_mangle]
pub unsafe fn check_to_pair(x: u64) -> Option<i32> {
// CHECK: %0 = alloca { i32, i32 }, align 4
// CHECK: store i64 %x, ptr %0, align 4
// CHECK: %_0 = alloca { i32, i32 }, align 4
// CHECK: store i64 %x, ptr %_0, align 4
transmute(x)
}

@@ -207,37 +203,37 @@ pub unsafe fn check_from_pair(x: Option<i32>) -> u64 {
// immediates so we can write using the destination alloca's alignment.
const { assert!(std::mem::align_of::<Option<i32>>() == 4) };

// CHECK: %0 = alloca i64, align 8
// CHECK: store i32 %x.0, ptr %1, align 8
// CHECK: store i32 %x.1, ptr %2, align 4
// CHECK: %3 = load i64, ptr %0, align 8
// CHECK: ret i64 %3
// CHECK: %_0 = alloca i64, align 8
// CHECK: store i32 %x.0, ptr %0, align 8
// CHECK: store i32 %x.1, ptr %1, align 4
// CHECK: %2 = load i64, ptr %_0, align 8
// CHECK: ret i64 %2
transmute(x)
}

// CHECK-LABEL: @check_to_float(
#[no_mangle]
pub unsafe fn check_to_float(x: u32) -> f32 {
// CHECK-NOT: alloca
// CHECK: %0 = bitcast i32 %x to float
// CHECK: ret float %0
// CHECK: %_0 = bitcast i32 %x to float
// CHECK: ret float %_0
transmute(x)
}

// CHECK-LABEL: @check_from_float(
#[no_mangle]
pub unsafe fn check_from_float(x: f32) -> u32 {
// CHECK-NOT: alloca
// CHECK: %0 = bitcast float %x to i32
// CHECK: ret i32 %0
// CHECK: %_0 = bitcast float %x to i32
// CHECK: ret i32 %_0
transmute(x)
}

// CHECK-LABEL: @check_to_bytes(
#[no_mangle]
pub unsafe fn check_to_bytes(x: u32) -> [u8; 4] {
// CHECK: %0 = alloca [4 x i8], align 1
// CHECK: store i32 %x, ptr %0, align 1
// CHECK: %_0 = alloca [4 x i8], align 1
// CHECK: store i32 %x, ptr %_0, align 1
transmute(x)
}

@@ -253,10 +249,10 @@ pub unsafe fn check_from_bytes(x: [u8; 4]) -> u32 {
// CHECK-LABEL: @check_to_aggregate(
#[no_mangle]
pub unsafe fn check_to_aggregate(x: u64) -> Aggregate64 {
// CHECK: %0 = alloca %Aggregate64, align 4
// CHECK: store i64 %x, ptr %0, align 4
// CHECK: %1 = load i64, ptr %0, align 4
// CHECK: ret i64 %1
// CHECK: %_0 = alloca %Aggregate64, align 4
// CHECK: store i64 %x, ptr %_0, align 4
// CHECK: %0 = load i64, ptr %_0, align 4
// CHECK: ret i64 %0
transmute(x)
}

@@ -273,7 +269,7 @@ pub unsafe fn check_from_aggregate(x: Aggregate64) -> u64 {
#[no_mangle]
pub unsafe fn check_long_array_less_aligned(x: [u64; 100]) -> [u16; 400] {
// CHECK-NEXT: start
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 2 %0, ptr align 8 %x, i64 800, i1 false)
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 2 %_0, ptr align 8 %x, i64 800, i1 false)
// CHECK-NEXT: ret void
transmute(x)
}
@@ -282,7 +278,7 @@ pub unsafe fn check_long_array_less_aligned(x: [u64; 100]) -> [u16; 400] {
#[no_mangle]
pub unsafe fn check_long_array_more_aligned(x: [u8; 100]) -> [u32; 25] {
// CHECK-NEXT: start
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %0, ptr align 1 %x, i64 100, i1 false)
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %_0, ptr align 1 %x, i64 100, i1 false)
// CHECK-NEXT: ret void
transmute(x)
}
@@ -301,8 +297,8 @@ pub unsafe fn check_pair_with_bool(x: (u8, bool)) -> (bool, i8) {
pub unsafe fn check_float_to_pointer(x: f64) -> *const () {
// CHECK-NOT: alloca
// CHECK: %0 = bitcast double %x to i64
// CHECK: %1 = inttoptr i64 %0 to ptr
// CHECK: ret ptr %1
// CHECK: %_0 = inttoptr i64 %0 to ptr
// CHECK: ret ptr %_0
transmute(x)
}

@@ -311,8 +307,8 @@ pub unsafe fn check_float_to_pointer(x: f64) -> *const () {
pub unsafe fn check_float_from_pointer(x: *const ()) -> f64 {
// CHECK-NOT: alloca
// CHECK: %0 = ptrtoint ptr %x to i64
// CHECK: %1 = bitcast i64 %0 to double
// CHECK: ret double %1
// CHECK: %_0 = bitcast i64 %0 to double
// CHECK: ret double %_0
transmute(x)
}

@@ -376,10 +372,10 @@ pub unsafe fn check_issue_110005(x: (usize, bool)) -> Option<Box<[u8]>> {
// CHECK-LABEL: @check_pair_to_dst_ref(
#[no_mangle]
pub unsafe fn check_pair_to_dst_ref<'a>(x: (usize, usize)) -> &'a [u8] {
// CHECK: %0 = inttoptr i64 %x.0 to ptr
// CHECK: %1 = insertvalue { ptr, i64 } poison, ptr %0, 0
// CHECK: %2 = insertvalue { ptr, i64 } %1, i64 %x.1, 1
// CHECK: ret { ptr, i64 } %2
// CHECK: %_0.0 = inttoptr i64 %x.0 to ptr
// CHECK: %0 = insertvalue { ptr, i64 } poison, ptr %_0.0, 0
// CHECK: %1 = insertvalue { ptr, i64 } %0, i64 %x.1, 1
// CHECK: ret { ptr, i64 } %1
transmute(x)
}

@@ -391,7 +387,7 @@ pub unsafe fn check_issue_109992(x: ()) -> [(); 1] {

// CHECK: start
// CHECK-NEXT: ret void
mir!{
mir! {
{
RET = CastTransmute(x);
Return()
@@ -408,7 +404,7 @@ pub unsafe fn check_unit_to_never(x: ()) {
// CHECK-NOT: trap
// CHECK: call void @llvm.trap
// CHECK-NOT: trap
mir!{
mir! {
let temp: ZstNever;
{
temp = CastTransmute(x);
@@ -425,7 +421,7 @@ pub unsafe fn check_unit_from_never(x: ZstNever) -> () {

// CHECK: start
// CHECK-NEXT: ret void
mir!{
mir! {
{
RET = CastTransmute(x);
Return()
@@ -457,10 +453,10 @@ pub struct HighAlignScalar(u8);
// CHECK-LABEL: @check_to_overalign(
#[no_mangle]
pub unsafe fn check_to_overalign(x: u64) -> HighAlignScalar {
// CHECK: %0 = alloca %HighAlignScalar, align 8
// CHECK: store i64 %x, ptr %0, align 8
// CHECK: %1 = load i64, ptr %0, align 8
// CHECK: ret i64 %1
// CHECK: %_0 = alloca %HighAlignScalar, align 8
// CHECK: store i64 %x, ptr %_0, align 8
// CHECK: %0 = load i64, ptr %_0, align 8
// CHECK: ret i64 %0
transmute(x)
}

21 changes: 21 additions & 0 deletions tests/codegen/issue-97217.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// compile-flags: -C opt-level=3
// ignore-debug: the debug assertions get in the way
#![crate_type = "lib"]

// Regression test for issue 97217 (the following should result in no allocations)

// CHECK-LABEL: @issue97217
#[no_mangle]
pub fn issue97217() -> i32 {
// drop_in_place should be inlined and never appear
// CHECK-NOT: drop_in_place

// __rust_alloc should be optimized out
// CHECK-NOT: __rust_alloc

let v1 = vec![5, 6, 7];
let v1_iter = v1.iter();
let total: i32 = v1_iter.sum();
println!("{}",total);
total
}
6 changes: 3 additions & 3 deletions tests/codegen/match-optimized.rs
Original file line number Diff line number Diff line change
@@ -20,13 +20,13 @@ pub fn exhaustive_match(e: E) -> u8 {
// CHECK-NEXT: unreachable
//
// CHECK: [[A]]:
// CHECK-NEXT: store i8 0, {{i8\*|ptr}} %1, align 1
// CHECK-NEXT: store i8 0, {{i8\*|ptr}} %_0, align 1
// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
// CHECK: [[B]]:
// CHECK-NEXT: store i8 1, {{i8\*|ptr}} %1, align 1
// CHECK-NEXT: store i8 1, {{i8\*|ptr}} %_0, align 1
// CHECK-NEXT: br label %[[EXIT]]
// CHECK: [[C]]:
// CHECK-NEXT: store i8 2, {{i8\*|ptr}} %1, align 1
// CHECK-NEXT: store i8 2, {{i8\*|ptr}} %_0, align 1
// CHECK-NEXT: br label %[[EXIT]]
match e {
E::A => 0,
2 changes: 1 addition & 1 deletion tests/codegen/mem-replace-big-type.rs
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big {
// For a large type, we expect exactly three `memcpy`s
// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big)
// CHECK-NOT: call void @llvm.memcpy
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false)
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %result, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false)
// CHECK-NOT: call void @llvm.memcpy
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %dest, {{i8\*|ptr}} align 8 %src, i{{.*}} 56, i1 false)
// CHECK-NOT: call void @llvm.memcpy
4 changes: 2 additions & 2 deletions tests/codegen/repeat-trusted-len.rs
Original file line number Diff line number Diff line change
@@ -8,13 +8,13 @@ use std::iter;
// CHECK-LABEL: @repeat_take_collect
#[no_mangle]
pub fn repeat_take_collect() -> Vec<u8> {
// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{[0-9]+}}, i8 42, i{{[0-9]+}} 100000, i1 false)
// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{.*}}, i8 42, i{{[0-9]+}} 100000, i1 false)
iter::repeat(42).take(100000).collect()
}

// CHECK-LABEL: @repeat_with_take_collect
#[no_mangle]
pub fn repeat_with_take_collect() -> Vec<u8> {
// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{[0-9]+}}, i8 13, i{{[0-9]+}} 12345, i1 false)
// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{.*}}, i8 13, i{{[0-9]+}} 12345, i1 false)
iter::repeat_with(|| 13).take(12345).collect()
}
2 changes: 1 addition & 1 deletion tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
Original file line number Diff line number Diff line change
@@ -152,7 +152,7 @@ pub extern "C" fn f_scalar_stack_1(
) {
}

// CHECK: define void @f_scalar_stack_2({{%Large\*|ptr}} {{.*}}sret{{.*}} %0, i64 noundef %a, i128 %1, i128 %2, i64 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g)
// CHECK: define void @f_scalar_stack_2({{%Large\*|ptr}} {{.*}}sret{{.*}} %_0, i64 noundef %a, i128 %0, i128 %1, i64 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g)
#[no_mangle]
pub extern "C" fn f_scalar_stack_2(
a: u64,

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -35,13 +35,13 @@ pub unsafe fn extract_s(v: S<4>, i: u32) -> f32 {
// CHECK-LABEL: @insert_m
#[no_mangle]
pub unsafe fn insert_m(v: M, i: u32, j: f32) -> M {
// CHECK: insertelement <4 x float> %{{v|1|2}}, float %j, i32 %i
// CHECK: insertelement <4 x float> %{{v|0|1}}, float %j, i32 %i
simd_insert(v, i, j)
}

// CHECK-LABEL: @insert_s
#[no_mangle]
pub unsafe fn insert_s(v: S<4>, i: u32, j: f32) -> S<4> {
// CHECK: insertelement <4 x float> %{{v|1|2}}, float %j, i32 %i
// CHECK: insertelement <4 x float> %{{v|0|1}}, float %j, i32 %i
simd_insert(v, i, j)
}
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@
// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]

#![allow(non_camel_case_types)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(inline_const)]
@@ -44,7 +43,7 @@ pub fn build_array_s(x: [f32; 4]) -> S<4> {
#[no_mangle]
pub fn build_array_transmute_s(x: [f32; 4]) -> S<4> {
// CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]]
// CHECK: store <4 x float> %[[VAL:.+]], {{ptr %0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
// CHECK: store <4 x float> %[[VAL:.+]], {{ptr %_0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
unsafe { std::mem::transmute(x) }
}

@@ -59,7 +58,7 @@ pub fn build_array_t(x: [f32; 4]) -> T {
#[no_mangle]
pub fn build_array_transmute_t(x: [f32; 4]) -> T {
// CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]]
// CHECK: store <4 x float> %[[VAL:.+]], {{ptr %0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
// CHECK: store <4 x float> %[[VAL:.+]], {{ptr %_0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
unsafe { std::mem::transmute(x) }
}

@@ -78,6 +77,6 @@ pub fn build_array_u(x: [f32; 4]) -> U {
#[no_mangle]
pub fn build_array_transmute_u(x: [f32; 4]) -> U {
// CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]]
// CHECK: store <4 x float> %[[VAL:.+]], {{ptr %0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
// CHECK: store <4 x float> %[[VAL:.+]], {{ptr %_0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
unsafe { std::mem::transmute(x) }
}
2 changes: 1 addition & 1 deletion tests/codegen/simd_arith_offset.rs
Original file line number Diff line number Diff line change
@@ -21,6 +21,6 @@ pub struct Simd<T, const LANES: usize>([T; LANES]);
// CHECK-LABEL: smoke
#[no_mangle]
pub fn smoke(ptrs: SimdConstPtr<u8, 8>, offsets: Simd<usize, 8>) -> SimdConstPtr<u8, 8> {
// CHECK: getelementptr i8, <8 x {{i8\*|ptr}}> %1, <8 x i64> %2
// CHECK: getelementptr i8, <8 x {{i8\*|ptr}}> %0, <8 x i64> %1
unsafe { simd_arith_offset(ptrs, offsets) }
}
8 changes: 4 additions & 4 deletions tests/codegen/slice-iter-len-eq-zero.rs
Original file line number Diff line number Diff line change
@@ -9,8 +9,8 @@ type Demo = [u8; 3];
#[no_mangle]
pub fn slice_iter_len_eq_zero(y: std::slice::Iter<'_, Demo>) -> bool {
// CHECK-NOT: sub
// CHECK: %2 = icmp eq {{i8\*|ptr}} {{%1|%0}}, {{%1|%0}}
// CHECK: ret i1 %2
// CHECK: %_0 = icmp eq {{i8\*|ptr}} {{%1|%0}}, {{%1|%0}}
// CHECK: ret i1 %_0
y.len() == 0
}

@@ -22,7 +22,7 @@ pub fn array_into_iter_len_eq_zero(y: std::array::IntoIter<Demo, 123>) -> bool {

// CHECK-NOT: icmp
// CHECK-NOT: sub
// CHECK: %1 = icmp eq {{i16|i32|i64}}
// CHECK: ret i1 %1
// CHECK: %_0 = icmp eq {{i16|i32|i64}}
// CHECK: ret i1 %_0
y.len() == 0
}
20 changes: 10 additions & 10 deletions tests/codegen/transmute-scalar.rs
Original file line number Diff line number Diff line change
@@ -11,24 +11,24 @@
// that allows us to avoid the `alloca`s entirely; see `rvalue_creates_operand`.

// CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float %x)
// CHECK: %0 = bitcast float %x to i32
// CHECK-NEXT: ret i32 %0
// CHECK: %_0 = bitcast float %x to i32
// CHECK-NEXT: ret i32 %_0
#[no_mangle]
pub fn f32_to_bits(x: f32) -> u32 {
unsafe { std::mem::transmute(x) }
}

// CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 zeroext %b)
// CHECK: %0 = zext i1 %b to i8
// CHECK-NEXT: ret i8 %0
// CHECK: %_0 = zext i1 %b to i8
// CHECK-NEXT: ret i8 %_0
#[no_mangle]
pub fn bool_to_byte(b: bool) -> u8 {
unsafe { std::mem::transmute(b) }
}

// CHECK-LABEL: define{{.*}}zeroext i1 @byte_to_bool(i8 %byte)
// CHECK: %0 = trunc i8 %byte to i1
// CHECK-NEXT: ret i1 %0
// CHECK: %_0 = trunc i8 %byte to i1
// CHECK-NEXT: ret i1 %_0
#[no_mangle]
pub unsafe fn byte_to_bool(byte: u8) -> bool {
std::mem::transmute(byte)
@@ -42,16 +42,16 @@ pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 {
}

// CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(ptr %p)
// CHECK: %0 = ptrtoint ptr %p to [[USIZE]]
// CHECK-NEXT: ret [[USIZE]] %0
// CHECK: %_0 = ptrtoint ptr %p to [[USIZE]]
// CHECK-NEXT: ret [[USIZE]] %_0
#[no_mangle]
pub fn ptr_to_int(p: *mut u16) -> usize {
unsafe { std::mem::transmute(p) }
}

// CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] %i)
// CHECK: %0 = inttoptr [[USIZE]] %i to ptr
// CHECK-NEXT: ret ptr %0
// CHECK: %_0 = inttoptr [[USIZE]] %i to ptr
// CHECK-NEXT: ret ptr %_0
#[no_mangle]
pub fn int_to_ptr(i: usize) -> *mut u16 {
unsafe { std::mem::transmute(i) }
11 changes: 6 additions & 5 deletions tests/codegen/uninit-consts.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// compile-flags: -C no-prepopulate-passes
// min-llvm-version: 15.0 (for opaque pointers)

// Check that we use undef (and not zero) for uninitialized bytes in constants.

@@ -8,7 +9,7 @@ use std::mem::MaybeUninit;

pub struct PartiallyUninit {
x: u32,
y: MaybeUninit<[u8; 10]>
y: MaybeUninit<[u8; 10]>,
}

// CHECK: [[FULLY_UNINIT:@[0-9]+]] = private unnamed_addr constant <{ [10 x i8] }> undef
@@ -25,30 +26,30 @@ pub struct PartiallyUninit {
#[no_mangle]
pub const fn fully_uninit() -> MaybeUninit<[u8; 10]> {
const M: MaybeUninit<[u8; 10]> = MaybeUninit::uninit();
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{[0-9]+}}, {{i8\*|ptr}} align 1 {{.*}}[[FULLY_UNINIT]]{{.*}}, i{{(32|64)}} 10, i1 false)
// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 1 %_0, ptr align 1 {{.*}}[[FULLY_UNINIT]]{{.*}}, i{{(32|64)}} 10, i1 false)
M
}

// CHECK-LABEL: @partially_uninit
#[no_mangle]
pub const fn partially_uninit() -> PartiallyUninit {
const X: PartiallyUninit = PartiallyUninit { x: 0xdeadbeef, y: MaybeUninit::uninit() };
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[PARTIALLY_UNINIT]]{{.*}}, i{{(32|64)}} 16, i1 false)
// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[PARTIALLY_UNINIT]]{{.*}}, i{{(32|64)}} 16, i1 false)
X
}

// CHECK-LABEL: @uninit_padding_huge
#[no_mangle]
pub const fn uninit_padding_huge() -> [(u32, u8); 4096] {
const X: [(u32, u8); 4096] = [(123, 45); 4096];
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[UNINIT_PADDING_HUGE]]{{.*}}, i{{(32|64)}} 32768, i1 false)
// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[UNINIT_PADDING_HUGE]]{{.*}}, i{{(32|64)}} 32768, i1 false)
X
}

// CHECK-LABEL: @fully_uninit_huge
#[no_mangle]
pub const fn fully_uninit_huge() -> MaybeUninit<[u32; 4096]> {
const F: MaybeUninit<[u32; 4096]> = MaybeUninit::uninit();
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[FULLY_UNINIT_HUGE]]{{.*}}, i{{(32|64)}} 16384, i1 false)
// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[FULLY_UNINIT_HUGE]]{{.*}}, i{{(32|64)}} 16384, i1 false)
F
}
2 changes: 1 addition & 1 deletion tests/codegen/union-abi.rs
Original file line number Diff line number Diff line change
@@ -73,4 +73,4 @@ pub union UnionBool { b:bool }
// CHECK: define {{(dso_local )?}}noundef zeroext i1 @test_UnionBool(i8 %b)
#[no_mangle]
pub fn test_UnionBool(b: UnionBool) -> bool { unsafe { b.b } }
// CHECK: %0 = trunc i8 %b to i1
// CHECK: %_0 = trunc i8 %b to i1
14 changes: 14 additions & 0 deletions tests/codegen/unwind-landingpad-cold.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// compile-flags: -Cno-prepopulate-passes
#![crate_type = "lib"]

// This test checks that drop calls in unwind landing pads
// get the `cold` attribute.

// CHECK-LABEL: @check_cold
// CHECK: {{(call|invoke) void .+}}drop_in_place{{.+}} [[ATTRIBUTES:#[0-9]+]]
// CHECK: attributes [[ATTRIBUTES]] = { cold }
#[no_mangle]
pub fn check_cold(f: fn(), x: Box<u32>) {
// this may unwind
f();
}
38 changes: 38 additions & 0 deletions tests/codegen/unwind-landingpad-inline.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// min-llvm-version: 15.0.0
// compile-flags: -Copt-level=3
// ignore-debug: the debug assertions get in the way
#![crate_type = "lib"]

// This test checks that we can inline drop_in_place in
// unwind landing pads.

// Without inlining, the box pointers escape via the call to drop_in_place,
// and LLVM will not optimize out the pointer comparison.
// With inlining, everything should be optimized out.
// See https://github.com/rust-lang/rust/issues/46515
// CHECK-LABEL: @check_no_escape_in_landingpad
// CHECK: start:
// CHECK-NEXT: ret void
#[no_mangle]
pub fn check_no_escape_in_landingpad(f: fn()) {
let x = &*Box::new(0);
let y = &*Box::new(0);

if x as *const _ == y as *const _ {
f();
}
}

// Without inlining, the compiler can't tell that
// dropping an empty string (in a landing pad) does nothing.
// With inlining, the landing pad should be optimized out.
// See https://github.com/rust-lang/rust/issues/87055
// CHECK-LABEL: @check_eliminate_noop_drop
// CHECK: start:
// CHECK-NEXT: call void %g()
// CHECK-NEXT: ret void
#[no_mangle]
pub fn check_eliminate_noop_drop(g: fn()) {
let _var = String::new();
g();
}
4 changes: 2 additions & 2 deletions tests/codegen/var-names.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ pub fn test(a: u32, b: u32) -> u32 {
// CHECK: %c = add i32 %a, %b
let d = c;
let e = d * a;
// CHECK-NEXT: %0 = mul i32 %c, %a
// CHECK-NEXT: %e = mul i32 %c, %a
e
// CHECK-NEXT: ret i32 %0
// CHECK-NEXT: ret i32 %e
}
5 changes: 0 additions & 5 deletions tests/ui/macros/auxiliary/proc_macro_sequence.rs
Original file line number Diff line number Diff line change
@@ -8,11 +8,6 @@ extern crate proc_macro;

use proc_macro::{quote, Span, TokenStream, TokenTree};

fn assert_same_span(a: Span, b: Span) {
assert_eq!(a.start(), b.start());
assert_eq!(a.end(), b.end());
}

// This macro generates a macro with the same macro definition as `manual_foo` in
// `same-sequence-span.rs` but with the same span for all sequences.
#[proc_macro]
19 changes: 19 additions & 0 deletions tests/ui/macros/rfc-3086-metavar-expr/issue-111905.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![feature(macro_metavar_expr)]

macro_rules! foo {
($($t:ident)*) => { ${count(t, 4294967296)} };
//~^ ERROR related fragment that refers the `count` meta-variable expression was not found
}

macro_rules! bar {
( $( { $( [ $( ( $( $t:ident )* ) )* ] )* } )* ) => { ${count(t, 4294967296)} }
//~^ ERROR related fragment that refers the `count` meta-variable expression was not found
}

fn test() {
foo!();
bar!( { [] [] } );
}

fn main() {
}
14 changes: 14 additions & 0 deletions tests/ui/macros/rfc-3086-metavar-expr/issue-111905.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: related fragment that refers the `count` meta-variable expression was not found
--> $DIR/issue-111905.rs:4:26
|
LL | ($($t:ident)*) => { ${count(t, 4294967296)} };
| ^^^^^^^^^^^^^^^^^^^^^^

error: related fragment that refers the `count` meta-variable expression was not found
--> $DIR/issue-111905.rs:9:60
|
LL | ( $( { $( [ $( ( $( $t:ident )* ) )* ] )* } )* ) => { ${count(t, 4294967296)} }
| ^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ macro_rules! a {
(
${count(foo, 0)},
${count(foo, 10)},
//~^ ERROR depth parameter on meta-variable expression `count` must be less than 4
//~^ ERROR depth parameter of meta-variable expression `count` must be less than 4
)
};
}
@@ -17,7 +17,7 @@ macro_rules! b {
${ignore(foo)}
${index(0)},
${index(10)},
//~^ ERROR depth parameter on meta-variable expression `index` must be less than 3
//~^ ERROR depth parameter of meta-variable expression `index` must be less than 3
)* )* )*
)
};
@@ -30,7 +30,7 @@ macro_rules! c {
${ignore(foo)}
${length(0)}
${length(10)}
//~^ ERROR depth parameter on meta-variable expression `length` must be less than 2
//~^ ERROR depth parameter of meta-variable expression `length` must be less than 2
)* )*
)
};
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
error: depth parameter on meta-variable expression `count` must be less than 4
error: depth parameter of meta-variable expression `count` must be less than 4
--> $DIR/out-of-bounds-arguments.rs:7:14
|
LL | ${count(foo, 10)},
| ^^^^^^^^^^^^^^^^

error: depth parameter on meta-variable expression `index` must be less than 3
error: depth parameter of meta-variable expression `index` must be less than 3
--> $DIR/out-of-bounds-arguments.rs:19:18
|
LL | ${index(10)},
| ^^^^^^^^^^^

error: depth parameter on meta-variable expression `length` must be less than 2
error: depth parameter of meta-variable expression `length` must be less than 2
--> $DIR/out-of-bounds-arguments.rs:32:18
|
LL | ${length(10)}
7 changes: 3 additions & 4 deletions tests/ui/macros/same-sequence-span.stderr
Original file line number Diff line number Diff line change
@@ -17,15 +17,14 @@ LL | $(= $z:tt)*
error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
--> $DIR/same-sequence-span.rs:19:1
|
LL | | }
| |_________________________________^ not allowed after `expr` fragments
LL |
LL | proc_macro_sequence::make_foo!();
| ^-------------------------------
| |
| _in this macro invocation
| |
LL | |
LL | |
LL | | fn main() {}
| |_________________________________^ not allowed after `expr` fragments
|
= note: allowed there are: `=>`, `,` or `;`
= note: this error originates in the macro `proc_macro_sequence::make_foo` (in Nightly builds, run with -Z macro-backtrace for more info)
11 changes: 1 addition & 10 deletions tests/ui/proc-macro/auxiliary/api/cmp.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
use proc_macro::{LineColumn, Punct, Spacing};
use proc_macro::{Punct, Spacing};

pub fn test() {
test_line_column_ord();
test_punct_eq();
}

fn test_line_column_ord() {
let line0_column0 = LineColumn { line: 0, column: 0 };
let line0_column1 = LineColumn { line: 0, column: 1 };
let line1_column0 = LineColumn { line: 1, column: 0 };
assert!(line0_column0 < line0_column1);
assert!(line0_column1 < line1_column0);
}

fn test_punct_eq() {
let colon_alone = Punct::new(':', Spacing::Alone);
assert_eq!(colon_alone, ':');
5 changes: 2 additions & 3 deletions tests/ui/proc-macro/auxiliary/assert-span-pos.rs
Original file line number Diff line number Diff line change
@@ -26,10 +26,9 @@ pub fn assert_span_pos(input: TokenStream) -> TokenStream {
let line: usize = str1.parse().unwrap();
let col: usize = str2.parse().unwrap();

let sp1s = sp1.start();
if (line, col) != (sp1s.line, sp1s.column) {
if (line, col) != (sp1.line(), sp1.column()) {
let msg = format!("line/column mismatch: ({}, {}) != ({}, {})", line, col,
sp1s.line, sp1s.column);
sp1.line(), sp1.column());
sp1.error(msg).emit();
}

2 changes: 1 addition & 1 deletion tests/ui/proc-macro/auxiliary/macro-only-syntax.rs
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@ fn expect_brace(tokens: &mut token_stream::IntoIter) -> token_stream::IntoIter {

fn check_useful_span(token: TokenTree, expected_filename: &str) {
let span = token.span();
assert!(span.start().column < span.end().column);
assert!(span.column() < span.end().column());

let source_path = span.source_file().path();
let filename = source_path.components().last().unwrap();
4 changes: 4 additions & 0 deletions tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,10 @@
// compile-flags: --crate-type lib --emit link
// normalize-stderr-test: "[^ ']*/dlltool.exe" -> "$$DLLTOOL"
// normalize-stderr-test: "[^ ]*/foo.def" -> "$$DEF_FILE"
// normalize-stderr-test: "[^ ]*/foo.lib" -> "$$LIB_FILE"
// normalize-stderr-test: "-m [^ ]*" -> "$$TARGET_MACHINE"
// normalize-stderr-test: "-f [^ ]*" -> "$$ASM_FLAGS"
// normalize-stderr-test: "--temp-prefix [^ ]*/foo.dll" -> "$$TEMP_PREFIX"
#[link(name = "foo", kind = "raw-dylib")]
extern "C" {
// `@1` is an invalid name to export, as it usually indicates that something
2 changes: 1 addition & 1 deletion tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Dlltool could not create import library:
error: Dlltool could not create import library with $DLLTOOL -d $DEF_FILE -D foo.dll -l $LIB_FILE $TARGET_MACHINE $ASM_FLAGS --no-leading-underscore $TEMP_PREFIX:
$DLLTOOL: Syntax error in def file $DEF_FILE:1

error: aborting due to previous error
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// run-pass
// needs-unwind (#73509)
// ignore-fuchsia Test must be run out-of-process

#![feature(test)]

9 changes: 9 additions & 0 deletions tests/ui/test-attrs/test-panic-abort.rs
Original file line number Diff line number Diff line change
@@ -11,9 +11,13 @@
// ignore-sgx no subprocess support

#![cfg(test)]
#![feature(test)]

extern crate test;

use std::io::Write;
use std::env;
use test::Bencher;

#[test]
fn it_works() {
@@ -48,3 +52,8 @@ fn no_residual_environment() {
}
}
}

#[bench]
fn benchmark(b: &mut Bencher) {
b.iter(|| assert_eq!(1 + 1, 2));
}
7 changes: 4 additions & 3 deletions tests/ui/test-attrs/test-panic-abort.run.stdout
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

running 5 tests
running 6 tests
test benchmark ... ok
test it_exits ... FAILED
test it_fails ... FAILED
test it_panics - should panic ... ok
@@ -18,13 +19,13 @@ testing123
testing321
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `2`,
right: `5`', $DIR/test-panic-abort.rs:34:5
right: `5`', $DIR/test-panic-abort.rs:38:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
it_exits
it_fails

test result: FAILED. 3 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
test result: FAILED. 4 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME