mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #147371 - Zalathar:rollup-897uitw, r=Zalathar
Rollup of 5 pull requests Successful merges: - rust-lang/rust#144908 (Fix doctest output json) - rust-lang/rust#147262 (Make #[link="dl"] an FCW rather than an error) - rust-lang/rust#147364 (update autodiff testcases) - rust-lang/rust#147367 (Trivial code cleanup in resolve) - rust-lang/rust#147369 (Fill out AVR target metadata) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
@@ -65,10 +65,22 @@ fn extend<'c>(
|
||||
cx: &'c mut AcceptContext<'_, '_, S>,
|
||||
args: &'c ArgParser<'_>,
|
||||
) -> impl IntoIterator<Item = Self::Item> + 'c {
|
||||
let mut result = None;
|
||||
let Some(items) = args.list() else {
|
||||
cx.expected_list(cx.attr_span);
|
||||
return result;
|
||||
let items = match args {
|
||||
ArgParser::List(list) => list,
|
||||
// This is an edgecase added because making this a hard error would break too many crates
|
||||
// Specifically `#[link = "dl"]` is accepted with a FCW
|
||||
// For more information, see https://github.com/rust-lang/rust/pull/143193
|
||||
ArgParser::NameValue(nv) if nv.value_as_str().is_some_and(|v| v == sym::dl) => {
|
||||
let suggestions = <Self as CombineAttributeParser<S>>::TEMPLATE
|
||||
.suggestions(cx.attr_style, "link");
|
||||
let span = cx.attr_span;
|
||||
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
|
||||
return None;
|
||||
}
|
||||
_ => {
|
||||
cx.expected_list(cx.attr_span);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let sess = cx.sess();
|
||||
@@ -113,7 +125,7 @@ fn extend<'c>(
|
||||
}
|
||||
};
|
||||
if !cont {
|
||||
return result;
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +214,7 @@ fn extend<'c>(
|
||||
}
|
||||
let Some((name, name_span)) = name else {
|
||||
cx.emit_err(LinkRequiresName { span: cx.attr_span });
|
||||
return result;
|
||||
return None;
|
||||
};
|
||||
|
||||
// Do this outside of the loop so that `import_name_type` can be specified before `kind`.
|
||||
@@ -218,15 +230,14 @@ fn extend<'c>(
|
||||
cx.emit_err(RawDylibNoNul { span: name_span });
|
||||
}
|
||||
|
||||
result = Some(LinkEntry {
|
||||
Some(LinkEntry {
|
||||
span: cx.attr_span,
|
||||
kind: kind.unwrap_or(NativeLibKind::Unspecified),
|
||||
name,
|
||||
cfg,
|
||||
verbatim,
|
||||
import_name_type,
|
||||
});
|
||||
result
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -741,14 +741,10 @@ fn throw_unresolved_import_error(
|
||||
errors.retain(|(_import, err)| match err.module {
|
||||
// Skip `use` errors for `use foo::Bar;` if `foo.rs` has unrecovered parse errors.
|
||||
Some(def_id) if self.mods_with_parse_errors.contains(&def_id) => false,
|
||||
_ => true,
|
||||
});
|
||||
errors.retain(|(_import, err)| {
|
||||
// If we've encountered something like `use _;`, we've already emitted an error stating
|
||||
// that `_` is not a valid identifier, so we ignore that resolve error.
|
||||
err.segment != Some(kw::Underscore)
|
||||
_ => err.segment != Some(kw::Underscore),
|
||||
});
|
||||
|
||||
if errors.is_empty() {
|
||||
self.tcx.dcx().delayed_bug("expected a parse or \"`_` can't be an identifier\" error");
|
||||
return;
|
||||
|
||||
@@ -874,6 +874,7 @@
|
||||
div,
|
||||
div_assign,
|
||||
diverging_block_default,
|
||||
dl,
|
||||
do_not_recommend,
|
||||
doc,
|
||||
doc_alias,
|
||||
|
||||
@@ -5,9 +5,9 @@ pub(crate) fn target() -> Target {
|
||||
arch: "avr".into(),
|
||||
metadata: crate::spec::TargetMetadata {
|
||||
description: None,
|
||||
tier: None,
|
||||
host_tools: None,
|
||||
std: None,
|
||||
tier: Some(3),
|
||||
host_tools: Some(false),
|
||||
std: Some(false),
|
||||
},
|
||||
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8:16-a:8".into(),
|
||||
llvm_target: "avr-unknown-unknown".into(),
|
||||
|
||||
+13
-17
@@ -12,7 +12,7 @@
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{Duration, Instant};
|
||||
use std::{fmt, panic, str};
|
||||
use std::{panic, str};
|
||||
|
||||
pub(crate) use make::{BuildDocTestBuilder, DocTestBuilder};
|
||||
pub(crate) use markdown::test as test_markdown;
|
||||
@@ -60,24 +60,15 @@ fn add_compilation_time(&mut self, duration: Duration) {
|
||||
self.added_compilation_times += 1;
|
||||
}
|
||||
|
||||
fn display_times(&self) {
|
||||
/// Returns `(total_time, compilation_time)`.
|
||||
fn times_in_secs(&self) -> Option<(f64, f64)> {
|
||||
// If no merged doctest was compiled, then there is nothing to display since the numbers
|
||||
// displayed by `libtest` for standalone tests are already accurate (they include both
|
||||
// compilation and runtime).
|
||||
if self.added_compilation_times > 0 {
|
||||
println!("{self}");
|
||||
if self.added_compilation_times == 0 {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for MergedDoctestTimes {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"all doctests ran in {:.2}s; merged doctests compilation took {:.2}s",
|
||||
self.total_time.elapsed().as_secs_f64(),
|
||||
self.compilation_time.as_secs_f64(),
|
||||
)
|
||||
Some((self.total_time.elapsed().as_secs_f64(), self.compilation_time.as_secs_f64()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,15 +393,20 @@ pub(crate) fn run_tests(
|
||||
if ran_edition_tests == 0 || !standalone_tests.is_empty() {
|
||||
standalone_tests.sort_by(|a, b| a.desc.name.as_slice().cmp(b.desc.name.as_slice()));
|
||||
test::test_main_with_exit_callback(&test_args, standalone_tests, None, || {
|
||||
let times = times.times_in_secs();
|
||||
// We ensure temp dir destructor is called.
|
||||
std::mem::drop(temp_dir.take());
|
||||
times.display_times();
|
||||
if let Some((total_time, compilation_time)) = times {
|
||||
test::print_merged_doctests_times(&test_args, total_time, compilation_time);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// If the first condition branch exited successfully, `test_main_with_exit_callback` will
|
||||
// not exit the process. So to prevent displaying the times twice, we put it behind an
|
||||
// `else` condition.
|
||||
times.display_times();
|
||||
if let Some((total_time, compilation_time)) = times.times_in_secs() {
|
||||
test::print_merged_doctests_times(&test_args, total_time, compilation_time);
|
||||
}
|
||||
}
|
||||
// We ensure temp dir destructor is called.
|
||||
std::mem::drop(temp_dir);
|
||||
|
||||
@@ -18,11 +18,6 @@
|
||||
// but each shadow argument is `width` times larger (thus 16 and 20 elements here).
|
||||
// `d_square3` instead takes `width` (4) shadow arguments, which are all the same size as the
|
||||
// original function arguments.
|
||||
//
|
||||
// FIXME(autodiff): We currently can't test `d_square1` and `d_square3` in the same file, since they
|
||||
// generate the same dummy functions which get merged by LLVM, breaking pieces of our pipeline which
|
||||
// try to rewrite the dummy functions later. We should consider to change to pure declarations both
|
||||
// in our frontend and in the llvm backend to avoid these issues.
|
||||
|
||||
#![feature(autodiff)]
|
||||
|
||||
@@ -30,7 +25,7 @@
|
||||
|
||||
// CHECK: ;
|
||||
#[no_mangle]
|
||||
//#[autodiff(d_square1, Forward, Dual, Dual)]
|
||||
#[autodiff_forward(d_square1, Dual, Dual)]
|
||||
#[autodiff_forward(d_square2, 4, Dualv, Dualv)]
|
||||
#[autodiff_forward(d_square3, 4, Dual, Dual)]
|
||||
fn square(x: &[f32], y: &mut [f32]) {
|
||||
@@ -79,25 +74,25 @@ fn main() {
|
||||
let mut dy3_4 = std::hint::black_box(vec![0.0; 5]);
|
||||
|
||||
// scalar.
|
||||
//d_square1(&x1, &z1, &mut y1, &mut dy1_1);
|
||||
//d_square1(&x1, &z2, &mut y2, &mut dy1_2);
|
||||
//d_square1(&x1, &z3, &mut y3, &mut dy1_3);
|
||||
//d_square1(&x1, &z4, &mut y4, &mut dy1_4);
|
||||
d_square1(&x1, &z1, &mut y1, &mut dy1_1);
|
||||
d_square1(&x1, &z2, &mut y2, &mut dy1_2);
|
||||
d_square1(&x1, &z3, &mut y3, &mut dy1_3);
|
||||
d_square1(&x1, &z4, &mut y4, &mut dy1_4);
|
||||
|
||||
// assert y1 == y2 == y3 == y4
|
||||
//for i in 0..5 {
|
||||
// assert_eq!(y1[i], y2[i]);
|
||||
// assert_eq!(y1[i], y3[i]);
|
||||
// assert_eq!(y1[i], y4[i]);
|
||||
//}
|
||||
for i in 0..5 {
|
||||
assert_eq!(y1[i], y2[i]);
|
||||
assert_eq!(y1[i], y3[i]);
|
||||
assert_eq!(y1[i], y4[i]);
|
||||
}
|
||||
|
||||
// batch mode A)
|
||||
d_square2(&x1, &z5, &mut y5, &mut dy2);
|
||||
|
||||
// assert y1 == y2 == y3 == y4 == y5
|
||||
//for i in 0..5 {
|
||||
// assert_eq!(y1[i], y5[i]);
|
||||
//}
|
||||
for i in 0..5 {
|
||||
assert_eq!(y1[i], y5[i]);
|
||||
}
|
||||
|
||||
// batch mode B)
|
||||
d_square3(&x1, &z1, &z2, &z3, &z4, &mut y6, &mut dy3_1, &mut dy3_2, &mut dy3_3, &mut dy3_4);
|
||||
|
||||
@@ -32,9 +32,9 @@ fn square2(x: &f64) -> f64 {
|
||||
// CHECK-NOT:br
|
||||
// CHECK-NOT:ret
|
||||
// CHECK:; call identical_fnc::d_square
|
||||
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square17hcb5768e95528c35fE(double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1)
|
||||
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH:.+]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1)
|
||||
// CHECK:; call identical_fnc::d_square
|
||||
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square17hcb5768e95528c35fE(double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2)
|
||||
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2)
|
||||
|
||||
fn main() {
|
||||
let x = std::hint::black_box(3.0);
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
//! ```
|
||||
//! let x = 12;
|
||||
//! ```
|
||||
@@ -0,0 +1,83 @@
|
||||
//! Regression test to ensure that the output format is respected for doctests.
|
||||
//!
|
||||
//! Regression test for <https://github.com/rust-lang/rust/issues/144798>.
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{rustdoc, serde_json};
|
||||
|
||||
fn run_test(edition: &str, format: Option<&str>) -> String {
|
||||
let mut r = rustdoc();
|
||||
r.input("file.rs").edition(edition).arg("--test");
|
||||
if let Some(format) = format {
|
||||
r.args(&[
|
||||
"--test-args",
|
||||
"-Zunstable-options",
|
||||
"--test-args",
|
||||
"--format",
|
||||
"--test-args",
|
||||
format,
|
||||
]);
|
||||
}
|
||||
r.run().stdout_utf8()
|
||||
}
|
||||
|
||||
fn check_json_output(edition: &str, expected_reports: usize) {
|
||||
let out = run_test(edition, Some("json"));
|
||||
let mut found_report = 0;
|
||||
for (line_nb, line) in out.lines().enumerate() {
|
||||
match serde_json::from_str::<serde_json::Value>(&line) {
|
||||
Ok(value) => {
|
||||
if value.get("type") == Some(&serde_json::json!("report")) {
|
||||
found_report += 1;
|
||||
}
|
||||
}
|
||||
Err(error) => panic!(
|
||||
"failed for {edition} edition (json format) at line {}: non-JSON value: {error}\n\
|
||||
====== output ======\n{out}",
|
||||
line_nb + 1,
|
||||
),
|
||||
}
|
||||
}
|
||||
if found_report != expected_reports {
|
||||
panic!(
|
||||
"failed for {edition} edition (json format): expected {expected_reports} doctest \
|
||||
time `report`, found {found_report}\n====== output ======\n{out}",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_non_json_output(edition: &str, expected_reports: usize) {
|
||||
let out = run_test(edition, None);
|
||||
let mut found_report = 0;
|
||||
for (line_nb, line) in out.lines().enumerate() {
|
||||
if line.starts_with('{') && serde_json::from_str::<serde_json::Value>(&line).is_ok() {
|
||||
panic!(
|
||||
"failed for {edition} edition: unexpected json at line {}: `{line}`\n\
|
||||
====== output ======\n{out}",
|
||||
line_nb + 1
|
||||
);
|
||||
}
|
||||
if line.starts_with("all doctests ran in")
|
||||
&& line.contains("; merged doctests compilation took ")
|
||||
{
|
||||
found_report += 1;
|
||||
}
|
||||
}
|
||||
if found_report != expected_reports {
|
||||
panic!(
|
||||
"failed for {edition} edition: expected {expected_reports} doctest time `report`, \
|
||||
found {found_report}\n====== output ======\n{out}",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Only the merged doctests generate the "times report".
|
||||
check_json_output("2021", 0);
|
||||
check_json_output("2024", 1);
|
||||
|
||||
// Only the merged doctests generate the "times report".
|
||||
check_non_json_output("2021", 0);
|
||||
check_non_json_output("2024", 1);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
warning: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", wasm_import_module = "...")]`
|
||||
--> $DIR/link-dl.rs:14:1
|
||||
|
|
||||
LL | #[link="dl"]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", wasm_import_module = "...")]`
|
||||
--> $DIR/link-dl.rs:14:1
|
||||
|
|
||||
LL | #[link="dl"]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
|
||||
= note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", wasm_import_module = "...")]`
|
||||
--> $DIR/link-dl.rs:14:1
|
||||
|
|
||||
LL | #[link="dl"]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
|
||||
= note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// Regression test for an issue discovered in https://github.com/rust-lang/rust/pull/143193/files and rediscovered in https://github.com/rust-lang/rust/issues/147254#event-20049906781
|
||||
// Malformed #[link] attribute was supposed to be deny-by-default report-in-deps FCW,
|
||||
// but accidentally was landed as a hard error.
|
||||
//
|
||||
// revision `default_fcw` tests that with `ill_formed_attribute_input` (the default) denied,
|
||||
// the attribute produces an FCW
|
||||
// revision `allowed` tests that with `ill_formed_attribute_input` allowed the test passes
|
||||
|
||||
//@ revisions: default_fcw allowed
|
||||
//@[allowed] check-pass
|
||||
|
||||
#[cfg_attr(allowed, allow(ill_formed_attribute_input))]
|
||||
|
||||
#[link="dl"]
|
||||
//[default_fcw]~^ ERROR valid forms for the attribute are
|
||||
//[default_fcw]~| WARN previously accepted
|
||||
extern "C" { }
|
||||
|
||||
fn main() {}
|
||||
Reference in New Issue
Block a user